Wicket PasswordTextField with Strength

I implemented a simple extension of the wicket PasswordTextField which provides you with an indication of the strength of the entered password (using regular expressions and returning “empty”, “weak”, “medium” or “strong”). Strong means at least 7 characters with mixed alphanumeric and non-alphanumeric characters. Medium means at least 6 characters with mixed alpha and non-alpha characters.

Originally I intended to make it a panel with a visual indicator (the usual spectrum from red through yellow to green), but then I figured that allowing the caller to make the styling decisions is better (if you want to display a spectrum, then add images to your styles and set the style on the component using an AttributeModifier – come to think of it, maybe I’ll do another post on how to do that…).

Anyway, here’s the component:

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

public abstract class PasswordTextFieldWithStrength extends PasswordTextField {
 private static final long serialVersionUID = 1L;

 public abstract void onUpdate(String passwordStrength, AjaxRequestTarget target);

 public PasswordTextFieldWithStrength(String id) {
  super(id);

  add(new OnChangeAjaxBehavior() {
   private static final long serialVersionUID = 1L;

   @Override
   protected void onUpdate(AjaxRequestTarget target) {
    String strength = getPasswordStrength(PasswordTextFieldWithStrength.this.getDefaultModelObjectAsString());
    PasswordTextFieldWithStrength.this.onUpdate(strength, target);
   }
  });
 }

 public String getStrength() {
  return getPasswordStrength(getDefaultModelObjectAsString());
 }

 private String getPasswordStrength(String password) {
  if (password.isEmpty())
   return "empty";

  String alphaPresent = ".*\w.*"; // at least one alpha character
  String nonAlphanumericPresent = ".*[^a-zA-Z0-9].*"; // at least one non-alphanumeric character
  String nonAlphaPresent = ".*[^a-zA-Z].*"; // at least one non-alpha character

  if (password.matches(alphaPresent) && password.matches(nonAlphanumericPresent) && password.length() >= 7)
   return "strong";

  if (password.matches(alphaPresent) && password.matches(nonAlphaPresent) && password.length() >= 6)
   return "medium";

  return "weak";
 }
}

And here’s how to use it:

// put a label on the form which will display the strength of the entered password
final Label passwordStrengthLabel = new Label("passwordStrength");
passwordStrengthLabel.setOutputMarkupId(true);
form.add(passwordStrengthLabel);

PasswordTextFieldWithStrength passwordField = new PasswordTextFieldWithStrength("password") {
  private static final long serialVersionUID = 1L;

And here's how it looks in an application
And here's how it looks in an application
@Override public void onUpdate(String strength, AjaxRequestTarget target) { // strength will be one of "empty", "weak", "medium", "strong" // you can put it into a label, use it as a key to load a localized string, use it to construct a style etc passwordStrength = getLocalizer().getString("passwordStrength_" + strength, this); target.addComponent(passwordStrengthLabel); } }; form.add(passwordField);

Keeping your database schemas in sync with your model

Hibernate’s hbm2ddl.auto setting allows you to create, update, and validate a database schemas based on the mapping configuration. The create & update settings are great in development environments, since they will ensure your database schema will always be in sync with your model. We would not recommend these settings in an production environment because, there we need to have more fine grained control over database updates (hbm2ddl is too “magical” for production). Additionally, there may be updates to the data which cannot be handled by Hibernate’s hbm2ddl.auto implementation (e.g. content-related updates rather than structural).

Some people would say, “such database updates should not be done by the application, but rather by the database administrator”. However, for most applications, you want the code to maintain the database structure – otherwise you have terrible trouble keeping test and staging databases up to date.

To achieve this we “upgrade” our databases with our own implementation, using plain JDBC. A meta table in the schema holds a version number which gets checked during the application’s start up. If the version in the database does not match the code version, the application upgrades the database schema accordingly.

We need to have our own database upgrade execute before Hibernate intercepts. Otherwise Hibernate will complain that tables or columns which should be created by our upgrade procedure are not yet available.

This can be achieved by a bean, which implements the BeanFactoryPostProcessor.

package sample;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class DatabaseVersion implements BeanFactoryPostProcessor {

 public static void checkDatabaseStructure() {
  /*
   * This method creates a generic JDBC connection,
   * checks the database structure
   * and upgrades it if applicable.
   */
 }

 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
  DatabaseVersion.chekDatabaseStructure();
 }
}

All what’s missing now is the definition of the bean in the applicationContext.xml file.


That’s it. The application context auto-detects BeanFactoryPostProcessor beans in their bean definitions and applys them before any other beans get created. If you are concearned about the order of loading, your bean can implement the “Ordered” interface in addition.

Corporate backup 2.0

Anyone who has a Mac is familiar with Time Machine, the almost magical, continuous backup capability of OSX. What many people may not know is that Time Machine is based on concepts which have been freely available for quite some time and which can easily be applied to corporate-wide backups. Because corporate backup is considered expensive to implement, many companies have outdated legacy backup systems based on tapes, tape-robots and offsite transport and storage of tapes. These systems are hopelessly outdated and can no longer keep up with the every increasing storage capacity of the disks they should be backing up and the decreasing backup time window in which backups should be completed.

We have approximately 3TB of data (consisting of about 40 databases, 200 virtual machines and hundreds of thousands of files) on our servers and workstations which need to be backed up. About a year ago we installed a comapny-wide backup to disk with offsite replication and versioning which has been providing us with continuous backup ever since. It continuously replicates a 4TB local RAID-6 disk-array offsite to a versioning 5TB RAID-6 disk array over a dedicated 4Mbps line, 24 hours a day, using rsync for the replication and snapshots based on Linux filesystem hard-links for versioning. Its implemented entirely on standard Linux components (zero license costs) and has been running without a glitch for over a year. Thanks to this system, we not only have an offsite backup of all business-critical data, but we can step back to any version of a database or virtual machine from yesterday, two days ago, four days ago, a week old, a month old etc. I can’t imagine why any company would still want to install a propietary backup system when such perfect technology is freely available.

Turnkey appliances

This blog is running on a Turnkey WordPress appliance (www.turnkeylinux.org). Virtual appliances are of course fantastic if they work – a fully configured, just-works server which you can download and provision in seconds (this blog took about 5 minutes to download, install on a VMWare Server virtual machine and get running). Until now, most appliances we tried had enough gotchas to make us return to manual installation on a generic distribution, but the Turnkey appliances seem to be perfect. Based on Ubuntu or Debian and with just enough stuff pre-installed to make them useful, while still being compact enough to compete with a manual installation. Thanks Turnkey!

Adding scripting to java applications

Many of our applications require scripting support (allowing users to create scripts to customize workflow within the application). Java provides very straightforward scripting via the javax.script script-engine library. A simple integration is shown below where a Javascript onSave method provided by the user is called, if available, passing a business-logic object “item”:

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Scripting extends Base {
 private ScriptEngineManager mgr;
 private ScriptEngine engine;
 private Invocable invocable;

 private boolean initialize (String script) {
  mgr = new ScriptEngineManager();
  engine = mgr.getEngineByName("js");
  try {
   engine.eval(script);
  } catch (ScriptException e) {
   warn("The script could not be loaded: " + e.getMessage());
   return false;
  }
  invocable = (Invocable)engine;
  return true;
 }

 public void onSave(Item item) {
  try {
   invocable.invokeFunction("onSave", item);
  } catch (ScriptException e) {
   warn("The onSave method of the script caused an error: " + e.getMessage());
  } catch (NoSuchMethodException e) {
   // no onSave method provided by the user - that's OK, just ignore it
  }
 }
}

Note: the javax.script library supports multiple scripting engines including javascript, python, groovy and java. Javascript was the easiest to get working because the Rhino Javascript engine is included in JDK 6.

A sessionless login page for Wicket applications

We’re big fans of Apache Wicket, but as with most frameworks, sometimes the simplest things appear to be hard to do (or at least its hard to find out how to do them). Application session handling is great in Wicket, but I immediately ran into the problem that the problem that the login page of my application would timeout like any other page of the application. If the user logged out (at which point the login page is displayed), left the browser window open and then tried to use the same browser window to login again an hour later, he’d get a “sorry, your session has timed out, please login again”.  This message obviously makes no sense on the login page.

The solution (thanks Doug Donohue for the help on this) is to use a stateless form for the login page (which causes Wicket to only create a temporary session for the page) and when the user has successfully logged in, convert the session to a regular session.

The relevant code fragments are shown below:

final StatelessForm form = new StatelessForm("loginForm", new CompoundPropertyModel(this)) {
 private static final long serialVersionUID = 1L;

 @Override
 protected void onSubmit() {
  try {
   validateUser(userid_or_email, password);
   if (getSession().isTemporary()) getSession().bind();
   // this makes the temporary session used by the stateless login page permanent
   ...
  }
  catch (Exception e) {
   error(e.getMessage());
  }
 }
};

Note however that you have to be very careful what components you use in a stateless page – otherwise you’ll suddenly find it to be stateful again (i.e. it will bind its session automatically and you’ll be back in the same situation). Basically anything which requires remembering a specific page instance (e.g. Ajax) will cause your page to become stateful.

There is some logic built into Wicket which should warn you when a page which you expect to be stateless becomes stateful, but it seems that in the latest versions of Wicket, these warnings are disabled. We ended up creating our own StatelessPage super-class which, in onBeforeRender, calls isPageStateless() and if that returns false, it runs through the components on the page and checks isStateless() for each and reports the wicket id for each component which is not stateless. That way, during development we can show a warning like “This page should be stateless, but isn’t because the following components are stateful: component1, component2…”

public class MyStatelessPage extends BasePage {

	@Override
	protected void onBeforeRender() {
		super.onBeforeRender();

		if (Settings.isOperatingModeDevelopment())
			checkIfPageStateless(this);
	}

	private void checkIfPageStateless(Page p) {
		if (!p.isPageStateless()) {
			// find out why
			final List statefulComponents = new ArrayList();
			p.visitChildren(Component.class, new IVisitor() {
				public Object component(Component component) {
					if (!component.isStateless())
						statefulComponents.add(component);
					return CONTINUE_TRAVERSAL;
				}
			});

			String message = "Whoops! this page is no longer stateless";
			if (statefulComponents.size() > 0) {
				message += " - the reason is that it contains the following stateful components: ";
				for (Component c : statefulComponents) {
					message += Settings.getNewLine() + c.getMarkupId();
				}
			}
			p.warn(message);
		}
	}
}

Quartz, Spring & Hibernate/JPA

Establishing a hibernate session in a wicket application is done by means of the OpenSessionInViewFilter class, which binds a Hibernate Session to the thread for the entire processing of the request. You’ll find plenty of references by googling for Wicket and Hibernate.

If you need background jobs to be executed, Quartz is a fantastic library, providing scheduling with cron syntax. Quartz is trivial to integrate into your application (whether with Spring or without), but we had a hard time to figure out how to handle Hibernate sessions correctly. When you want to use one of your DAOs in a Quartz Job you are very likely to hit a “Session is closed!” exception from Hibernate. The reason for this is that the Quartz Job does not run within the context of the servlet, therefore nobody took care of establishing a Hibernate Session.

Below you’ll find a sample Quartz Job which shows how to set up the Hibernate session like OpenSessionInViewFilter does during a servlet request:

package sample;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class SampleJobBean extends QuartzJobBean {

  @Override
  protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    EntityManagerFactory emf = null;
    EntityManager em = null;
    try {
      ApplicationContext appContext = (ApplicationContext) jobExecutionContext.getScheduler().getContext().get("applicationContext");
      EntityManagerFactory emf = (EntityManagerFactory) appContext.getBean("entityManagerFactory", EntityManagerFactory.class);
      em = emf.createEntityManager();
      TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em));

      /* Some action */

    } catch (Exception e) {
      //Exception handling..
      e.printStackTrace();
    }
    finally{
      if (em!=null) em.close();
    }
  }
}

Below you’ll find the relevant sections from the corresponding applicationContext.xml file.



  
    
  


  
    
  



  
    
      
    
  
  
    applicationContext
  




  

Thanks to Uwe Schäfer who helped us find this solution!