Enumerated Types

Enumerated Type (com.javelin.beans.EnumeratedType)

Enumerated Types gives a powerful, but simple way of specifying static enumerations of key, name pairs. For example Frequency or Marital Status. Enumerated Types keep type definitions in one place.

All Enumerated Types implement the EnumeratedType interface, which has the two methods.

public Object getKey();

public String getName();

The key gives a unique key for the enumerated value and the name gives a displayable name. The key is the value that is persisted in the store, and name is (generally) the value that is displayed.

Implementations of Enumerated Types contain a static member for each type. These static members are declared, for example: -

public final static Frequency MONTHLY = new Frequency( new Integer( 30 ), "Monthly" );

The key can be one of the following: -

  • String
  • Character
  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double

Abstract Enumerated Type

The EnumeratedType classes that are generated extend the com.javelin.beans.AbstractEnumeratedType class.

This provides a number of utility methods that makes it easy to implement Enumerated Types easier.

  • AbstractEnumeratedType() - constructor with type and name.
  • getType() - implement Enumerated Type interface.
  • getName() -implement Enumerated Type interface.
  • findType() - find a type by name or key.
  • getType() -get a type by name or key.
  • getTypeByMatch() - match a type by name.
  • toString() - object method.
  • hashCode() - object method.
  • equals() - object method.

Enumerated Type Writer (com.javelin.generator.beans.EnumeratedTypeWriter)

The EnumeratedTypeWriter class is responsible for writing EnumeratedType classes. A single class is created for each Enumeration, of the same name.

The Enumerated Type class is created in the default package. The EnumeratedType package or parent class can be modified by changing the following line in the defaultbdl.properties file: -

$ENUMERATEDTYPE=public class $PACKAGE.$THIS extends $BEANS.AbstractEnumeratedType

Enumerated Type Properties

For each EnumeratedType a Class is created, with a number of static members accessor methods.

An Enumerated Type is specified in the properties file with the following syntax: -

<EnumeratedTypeName>=public class <Fully Qualified Class Name> extends $ENUMERATED_TYPE

e.g.

MaritalStatus=public class $PACKAGE.MaritalStatus extends $ENUMERATED_TYPE

Then for each Enumerated Type type specify it as follows:-

<EnumeratedTypeName>.enum.<Index>=<Name>,<Value>,<Title>

e.g.

MaritalStatus.enum.0=SINGLE,"S",Single
MaritalStatus.enum.1=PARTNER,"I",Intended
MaritalStatus.enum.2=MARRIED,"M",Married
MaritalStatus.enum.3=DIVORCED,"D",Divorced
MaritalStatus.enum.4=WIDOWED,"W",Widowed

The underlying type of the Enumerated Type (in this example a String) is determined by looking up the Enumerated Type in the database.

This will produce a class called MaritalStatus with the following static members: -

public final static String SINGLE = new MaritalStatus( "S", "Single" );
public final static String INTENDED = new MaritalStatus( "I", "Intended" );
public final static String MARRIED = new MaritalStatus( "M", "Married" );
public final static String DIVORCED = new MaritalStatus( "D", "Divorced" );
public final static String WIDOWED = new MaritalStatus( "W", "Widowed" );

Having static member makes it easy for code completion. For example, in most Java editors typing the word Customer, should throw up the setMaritalStatus method. After choosing this method the MaritalStatus argument should appear, putting a dot after this should list all the marital status's.

customer.setMaritalStatus( MaritalStatus.MARRIED );

AccessorMethods

Every Enumerated type can has a number accessor methods to find the Enumerated Types.

The findBy methods access the Enumerated Type using it's key, and throw a FinderException if the type cannot be found. If the Enumerated Type is a number, a method is also created with a primitive type as an argument. The findBy methods have following pattern: -

public static <Enumerated Type> findByKey( <object key> key ) throws FinderException
public static <Enumerated Type> findByKey( <primitive key> key ) throws FinderException

The getBy methods access the Enumerated Type using it's key, and return null if the type cannot be found. If the Enumerated Type is a number, a method is also created with a primitive type as an argument. The getBy methods have following pattern: -

public static <Enumerated Type> getByKey( <object key> key )
public static <Enumerated Type> getByKey( <primitive key> key )

The findByName and getByName methods access the Enumerated Type using it's name, and either throw a FinderException or return null if the type cannot be found. The findByName and getByName methods have following pattern: -

public static <Enumerated Type> findByName( String name ) throws FinderException
public static <Enumerated Type> getByName( String name )

The findByMatch and getByMatch methods access the Enumerated Type using it's key or name (case insensitive), and either throw a FinderException or return null if the type cannot be found. These match methods are useful when trying load data using a string, with a more flexible formatting. The findByMatch and getByMatch methods have following pattern: -

public static <Enumerated Type> findByMatch( String match ) throws FinderException
public static <Enumerated Type> getByMatch( String match )

Subsets

Applications often want to determine if an Enumerated Type is a member of a subset. For example if a persons MaritalStatus means they have been married. Similarly an application may want to display a subset (or all) the types in a combo.

The EnumeratedTypeWriter can write out additional methods with the following pattern: -

public static Enumeration find<SubsetName>()
public static boolean is<SubsetName>( <Enumerated Type> object )

Subsets are added to the Enumerated Type using the following syntax: -

<Enumerated Type>.find.<index>=<subsetName>,<Name>[,<Name> ...]

For example to create a list of all the MaritalStatus, and to check whether a person has been married specify the following: -

MaritalStatus.find.0=all,SINGLE,INTENDED,MARRIED,DIVORCED,WIDOWED
MaritalStatus.find.1=beenMarried,MARRIED,DIVORCED,WIDOWED

This will produce the following methods: -

public static Enumeration findAll()
public static boolean isAll( MaritalStatus object )

public static Enumeration findBeenMarried()
public static boolean isBeenMarried( MaritalStatus object )

Validating Subsets

A property can be validated to belong to a subset, using the following syntax:-

<ClassName>.<propertyName>.validSubset=<SubsetName>

For example if we only wanted to allow people who are married or had been married we would state the following in the properties file: -

Person.maritalStatus.validSubset=beenMarried

Adding to a Table

Enumerated Types can be added to a table by simply including the type by name. The PropertiesReader will automatically map the type name, for example.

readColumn.PaymentInstructions.3=frequency INT

The same Enumerated Type can be included several times on the same table by using a simple mapping property. For example: -

readColumn.PaymentInstructions.3=settlementFrequency INT
readColumn.PaymentInstructions.3=calculationFrequency INT

PaymentInstructions.settlementFrequency=Frequency
PaymentInstructions.calculationFrequency=Frequency

Using Enumerated Types

Enumerated Types provide a really useful way to efficiently store key name pairs, so that only the key is stored.

Enumerated Types are useful to render Swing or JSP combos. These combos can be used to display subsets of EnumeratedTypes, for example: -

JSPUtil.renderNullCombo( "maritalStatus", MaritalStatus.findUnmarried() );

JCombo unmarriedCombo = new JEnumeratedTypeCombo( MaritalStatus.findUnmarried() );

Enumerated Types are useful to use in Java Editors, the code completion means that all the Enumerated Type options are available, for example: -

person.setMaritalStatus( MaritalStatus. );

Example Enumerated Type

Here is an example Frequency Enumerated type to give the big picture of what can be generated: -

/*
* Copyright Javelin Software, All rights reserved.
*/

package com.javelin.jcommerce;

import java.io.*;
import java.util.*;
import com.javelin.jcommerce.*;
import com.javelin.beans.*;

/**
* Frequency.java
*
* @version 1.0
* @author Javelin Software
*/

public class Frequency extends AbstractEnumeratedType
{

protected static Hashtable cache = new Hashtable();
protected static Hashtable stringCache = new Hashtable();

/**
* DAILY, 1, Daily.
*/
public final static Frequency DAILY = new Frequency( new Integer( 1 ), "Daily" );

/**
* WEEKLY, 7, Weekly.
*/
public final static Frequency WEEKLY = new Frequency( new Integer( 7 ), "Weekly" );

/**
* MONTHLY, 30, Monthly.
*/
public final static Frequency MONTHLY = new Frequency( new Integer( 30 ), "Monthly" );

/**
* QUARTERLY, 120, Quarterly.
*/
public final static Frequency QUARTERLY = new Frequency( new Integer( 120 ), "Quarterly" );

/**
* SEMI_ANNUALLY, 240, Semi-Annually.
*/
public final static Frequency SEMI_ANNUALLY = new Frequency( new Integer( 240 ), "Semi-Annually" );

/**
* ANNUALLY, 365, Annually.
*/
public final static Frequency ANNUALLY = new Frequency( new Integer( 365 ), "Annually" );

/**
* Construct a fully qualified Frequency.
*/
public Frequency( java.lang.Integer key, String name ) throws IllegalArgumentException
{
super( key, name );

if( cache.get( key ) != null )
{
throw new IllegalArgumentException( "Frequency already has a key " + key );
}

cache.put( key, this );
stringCache.put( name.toString().toUpperCase(), this );
}

/**
* Find the EnumeratedType by the Key.
*/
public static Frequency findByKey( int key ) throws FinderException
{
return (Frequency)findType( new Integer( key ), Frequency.class, cache );
}

/**
* Find the EnumeratedType by the Key.
*/
public static Frequency findByKey( Integer key ) throws FinderException
{
return (Frequency)findType( key, Frequency.class, cache );
}

/**
* Get the EnumeratedType by the primitive Key.<br>
* This will not throw a Finder Exception.
*/
public static Frequency getByKey( int key )
{
return(Frequency)getType( new Integer( key ), Frequency.class, cache );
}

/**
* Get the EnumeratedType by the Key.<br>
* This will not throw a Finder Exception.
*/
public static Frequency getByKey( Integer key ) throws FinderException
{
return(Frequency)getType( key, Frequency.class, cache );
}

/**
* Find the EnumeratedType by the Name, as String.
*/
public static Frequency findByName( String name ) throws FinderException
{
return (Frequency)findType( name == null ? null : name.toUpperCase(), Frequency.class, stringCache );
}

/**
* Get the EnumeratedType by the Key, as a String.<br>
* This will not throw a Finder Exception.
*/
public static Frequency getByName( String name )
{
return(Frequency)getType( name == null ? null : name.toUpperCase(), Frequency.class, stringCache );
}

/**
* Find the EnumeratedType matching the String against the key and name.<br>
*/
public static Frequency findByMatch( String match ) throws FinderException
{
return(Frequency)findTypeByMatch( match, Frequency.class, cache );
}

/**
* Get the EnumeratedType matching the String against the key and name.<br>
*/
public static Frequency getByMatch( String match )
{
return(Frequency)getTypeByMatch( match, Frequency.class, cache );
}

private static Vector all = new Vector();

static
{
all.addElement( DAILY );
all.addElement( WEEKLY );
all.addElement( MONTHLY );
all.addElement( QUARTERLY );
all.addElement( SEMI_ANNUALLY );
all.addElement( ANNUALLY );
}

/**
* Find all.
*/
public static Enumeration findAll()
{
return all.elements();
}

/**
* Contains all.
*/
public static boolean isAll( Frequency object )
{
return all.contains( object );
}

}