Saturday, October 31, 2009

Date validation with Java

Even though there are many fancy calendar inputs on the internet, sometimes, the easiest way to let simple users to input date in web application is by using 3 drop downs: day, month and year. On the server side, we combine these 3 values to create a proper date instance. But, before converting these 3 values to date we need to make sure, the values create a valid date. There are few cases in which an invalid date can be inputted. For example, when a month with 30 days is selected along with day: 31.

Validating that the 3 values: day, month, year really constructs a proper date is an easy task in Java. But, the idea behind it, is not as trivial as it looks. The calendar class can create date instance from day, month and year, but it doesn’t make sure the values are in the range. For example, day with values 33 can be accepted without an exception being raised.

In order to make sure a date is valid we will do a small trick:

  • Construct a string date representation for the inputted values: day, month, year (we can choose any format).
  • Convert the string date to a java date instance by using a date formatter.
  • Convert the date back to a string again.
  • Check the original string we built against the converted date.

If both strings are equal, that means date is valid.

Here is the Java code that does the task:

package com.bashan.blog.date;
import org.apache.commons.lang.StringUtils;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.Format;
import java.text.ParseException;
public class DateUtil {
  public static boolean isDateValid(int day, int month, int year)
  {
    try
    {
      String date = StringUtils.leftPad(day + "", 2, "0") + "/" + StringUtils.leftPad(month + "", 2, "0") + "/" + year;
      String dateFormat = "dd/MM/yyyy";
      Date dateSimple = new SimpleDateFormat(dateFormat).parse(date);
      Format formatter = new SimpleDateFormat(dateFormat);
      return date.equals(formatter.format(dateSimple));
    }
    catch (ParseException e)
    {
      return false;
    }
  }
}

Note that this code uses StringUtils.leftPad method, which is part of Apache Commons Lang project.

Monday, October 12, 2009

Java Servlet that returns a transparent pixel

Advertising and web analytic services use many techniques and tricks in order to track user impressions and actions. One of the common ways of tracking users is by placing an image tag on a page. The image tag generates a request to some image and in addition to serving the image some statistics is being collected. This technique is used in order to reduce integration processes to a minimum. All needed to be done, is simply to place the image tag somewhere in the HTML web page, set some parameters if desired (passed by the url of the image), and that’s it. No need to worry from JavaScript not supported or Third party cookies being blocked.

An example for such a request can look like:

<img src="www.myservice.com/count?customerId=7 />

In this example, by placing the image tag in a web page, we are making a request to the server: www.myservice.co with the parameter: customerId=7, meaning the customer that sent the request is identified in our system as “7”.

Note, that we didn’t make any call to a real image. We made a request to a Java Servlet that generates for us a transparent image of one pixel. We want the image response to be as small a possible for 2 reasons:

  • The traffic from our server back to the client will be minimal. A reduction of traffic yields a better performance as well as reduced server traffic costs.
  • We want the image to be a small as possible, so it won’t be noticed and effect the layout of the page. For this reason we also return a transparent pixel.

Let see how we dynamically create a transparent image of one pixel and serve it back to the client:

package com.bashan.blog.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
public class PixelServlet extends HttpServlet {
  private BufferedImage pixel;
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    pixel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
    pixel.setRGB(0, 0, (0xFF));
  }
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Here we can do whatever logic we want   
    response.setContentType("image/png");
    OutputStream os = response.getOutputStream();
    ImageIO.write(pixel, "png", os);
  }
}

Note that when the Servlet is being initialized we create the pixel and make it transparent. On the “doGet” method we write the pixel to the outputStream of the response.

Of course, instead of serving the pixel this way, we can simply put a transparent image of a pixel in the root of our web server, and make a redirection to this pixel, but usually tracking pixels are known to be requested by lots of clients simultaneously, so in terms of performance, it is better to directly write the pixel to the stream.

Don't forget to declare and map this Servlet in your web.xml to make it usable...

Saturday, October 3, 2009

User Type Enumeration in Hibernate Annotations

There are times we would like to work with enum types in Hibernate, but we would like the enum name to be different then the enum value in the database. For example, we would like the Java enum name to be in upper case and the database enum name to be in lower case.

This feature can be achieved by creating a Hibernate user type enumeration. The code for this kind of enumeration can be found on the web, but I will post this code here anyway (that it will be easier). The main goal of this post, is to demonstrate how such a user type enumeration can be used with Annotations.

Here are the classes for creating the user type enumerations:

First is the interface defining a method: “getValue”, which returns the actual value of the enumeration. This value is the value that is written to the database table:

package com.bashan.blog.persistence;
/**
 * Utility class designed to allow dinamic fidding and manipulation of Enum
 * instances which hold a string value.
 */
public interface StringValuedEnum {
    /**
     * Current string value stored in the enum.
     * @return string value.
     */
    public String getValue();
}

The second class:

package com.bashan.blog.persistence;
/**
 * Utility class designed to inspect StringValuedEnums.
 */
public class StringValuedEnumReflect
{
  /**
   * Don't let anyone instantiate this class.
   *
   * @throws UnsupportedOperationException Always.
   */
  private StringValuedEnumReflect()
  {
    throw new UnsupportedOperationException("This class must not be instanciated.");
  }
  /**
   * All Enum constants (instances) declared in the specified class.
   *
   * @param enumClass Class to reflect
   * @return Array of all declared EnumConstants (instances).
   */
  private static <T extends Enum> T[]
  getValues(Class<T> enumClass)
  {
    return enumClass.getEnumConstants();
  }
  /**
   * All possible string values of the string valued enum.
   *
   * @param enumClass Class to reflect.
   * @return Available string values.
   */
  public static <T extends Enum & StringValuedEnum> String[]
  getStringValues(Class<T> enumClass)
  {
    T[] values = getValues(enumClass);
    String[] result = new String[values.length];
    for (int i = 0; i < values.length; i++)
    {
      result[i] = values[i].getValue();
    }
    return result;
  }
  /**
   * Name of the enum instance which hold the especified string value.
   * If value has duplicate enum instances than returns the first occurency.
   *
   * @param enumClass Class to inspect.
   * @param value     String.
   * @return name of the enum instance.
   */
  public static <T extends Enum & StringValuedEnum> String
  getNameFromValue(Class<T> enumClass, String value)
  {
    T[] values = getValues(enumClass);
    for (int i = 0; i < values.length; i++)
    {
      if (values[i].getValue().compareTo(value) == 0)
      {
        return values[i].name();
      }
    }
    return "";
  }
}

And the last one:

package com.bashan.blog.persistence;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
import java.lang.reflect.*;
import org.hibernate.HibernateException;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.ParameterizedType;
import static com.todacell.ui.model.persistence.StringValuedEnumReflect.*;
//Please notice the calls to getNameFromValue *************************
public class StringValuedEnumType<T extends Enum & StringValuedEnum>
    implements EnhancedUserType, ParameterizedType
{
  /**
   * Enum class for this particular user type.
   */
  private Class<T> enumClass;
  /**
   * Value to use if null.
   */
  private String defaultValue;
  /**
   * Creates a new instance of ActiveStateEnumType
   */
  public StringValuedEnumType()
  {
  }
  public void setParameterValues(Properties parameters)
  {
    String enumClassName = parameters.getProperty("enum");
    try
    {
      enumClass = (Class<T>)Class.forName(enumClassName).asSubclass(Enum.class).
          asSubclass(StringValuedEnum.class); //Validates the class but does not eliminate the cast
    } catch (ClassNotFoundException cnfe)
    {
      throw new HibernateException("Enum class not found", cnfe);
    }
    setDefaultValue(parameters.getProperty("defaultValue"));
  }
  public String getDefaultValue()
  {
    return defaultValue;
  }
  public void setDefaultValue(String defaultValue)
  {
    this.defaultValue = defaultValue;
  }
  /**
   * The class returned by <tt>nullSafeGet()</tt>.
   *
   * @return Class
   */
  public Class returnedClass()
  {
    return enumClass;
  }
  public int[] sqlTypes()
  {
    return new int[]{Types.VARCHAR};
  }
  public boolean isMutable()
  {
    return false;
  }
  /**
   * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
   * should handle possibility of null values.
   *
   * @param rs    a JDBC result set
   * @param names the column names
   * @param owner the containing entity
   * @return Object
   * @throws HibernateException
   * @throws SQLException
   */
    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            throws HibernateException, SQLException {
        String value = rs.getString( names[0] );
        if (value==null) {
            value = getDefaultValue();
            if (value==null){ //no default value
                return null;
            }
        }
        String name = getNameFromValue(enumClass, value);
        Object res = name == null ? null : Enum.valueOf(enumClass, name);
        return res;
    }

  /**
   * Write an instance of the mapped class to a prepared statement. Implementors
   * should handle possibility of null values. A multi-column type should be written
   * to parameters starting from <tt>index</tt>.
   *
   * @param st    a JDBC prepared statement
   * @param value the object to write
   * @param index statement parameter index
   * @throws HibernateException
   * @throws SQLException
   */
  public void nullSafeSet(PreparedStatement st, Object value, int index)
      throws HibernateException, SQLException
  {
    if (value == null)
    {
      st.setNull(index, Types.VARCHAR);
    }
    else
    {
      st.setString(index, ((T)value).getValue());
    }
  }
  public Object assemble(Serializable cached, Object owner)
      throws HibernateException
  {
    return cached;
  }
  public Serializable disassemble(Object value) throws HibernateException
  {
    return (Enum)value;
  }
  public Object deepCopy(Object value) throws HibernateException
  {
    return value;
  }
  public boolean equals(Object x, Object y) throws HibernateException
  {
    return x == y;
  }
  public int hashCode(Object x) throws HibernateException
  {
    return x.hashCode();
  }
  public Object replace(Object original, Object target, Object owner)
      throws HibernateException
  {
    return original;
  }
  public String objectToSQLString(Object value)
  {
    return '\'' + ((T)value).getValue() + '\'';
  }
  public String toXMLString(Object value)
  {
    return ((T)value).getValue();
  }
  public Object fromXMLString(String xmlValue)
  {
    String name = getNameFromValue(enumClass, xmlValue);
    return Enum.valueOf(enumClass, name);
  }
}

Here is an example how this user type enumeration is used:

package com.bashan.blog.persistence;
public enum Gender implements StringValuedEnum {
  MALE("male"),
  FEMALE("female");
  private final String gender;
  Gender(final String gender)
  {
    this.gender = gender;
  }
  public String getValue()
  {
    return this.gender;
  }
}

And here is an example how the enum Gender is used as a member in an Hibernate Entity class Person:

package com.bashan.blog.persistence;
import org.hibernate.annotations.Entity;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.validator.Length;
import org.hibernate.validator.NotNull;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@Entity
@Table(name = "person")
public class Person implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "person_id")
    private Integer personId;
    @Column(name = "first_name")
    @NotNull
    @Length(max = 50)
    private String firstName;
    @Column(name = "last_name")
    @NotNull
    @Length(max = 50)
    private String lastName;
    @Column(name = "birth_date")
    private Date birthDate;
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person")
    @JoinColumn(name = "person_id")
    @Column(name = "gender")
    @Type(type = "com.todacell.ui.model.persistence.StringValuedEnumType",
            parameters = @Parameter(name = "enum", value = "com.bashan.blog.persistence.Gender"))
    @NotNull
    private Gender gender;
    public Integer getPersonId() {
        return personId;
    }
    public void setPersonId(Integer personId) {
        this.personId = personId;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Date getBirthDate() {
        return birthDate;
    }
    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }
    public Gender getGender() {
        return gender;
    }
    public void setGender(Gender gender) {
        this.gender = gender;
    }
}

The part in which the enum is used is marked in yellow.

You can grab all the sources for this post here.