<?xml version="1.0" encoding="ISO-8859-1"?>
<document url="http://castor.org/howto/how-to-use-a-cache.xml">
  <properties>
    <title>How to map typesafe enumerations with Castor</title>
    <abstract>
       General information about using typesafe enumerations with Castor
    </abstract>
    <status>Final</status>
  </properties>
  <body>
    <title>How to map typesafe enumerations with Castor</title>
    <header>
    </header>

    <section title="Intended Audience">

        <p>Anyone who wants to persist object that refer to a typesafe enumeration.</p>
        
        <p>This document addresses the basics and shows an example how to map an object that has a
		typesafe enumeration property.</p>
        
    </section>
    
    <section title="Prerequisites">

        <p>Enumerations are a common method for ensuring data integrity, both in software and
        in relational databases. As a platform for linking the two, we added support for
        persisting class fields whose type is a Java typesafe enumeration to Castor JDO.</p>
					
        <p>To use this new feature your typesafe enumeration should follow the enum pattern
        commonly used and provide a <tt>static valueOf(String)</tt> method. An enum of
        different kinds of computer equipment may look like:</p>

            <code-panel>
public class KindEnum {
    private static final Map KINDS = new HashMap();

    public static final KindEnum MOUSE = new KindEnum("Mouse");
    public static final KindEnum KEYBOARD = new KindEnum("Keyboard");
    public static final KindEnum COMPUTER = new KindEnum("Computer");
    public static final KindEnum PRINTER = new KindEnum("Printer");
    public static final KindEnum MONITOR = new KindEnum("Monitor");

    private final String _kind;

    private KindEnum(final String kind) {
        _kind = kind;
        KINDS.put(kind, this);
    }

    public static KindEnum valueOf(final String kind) {
	    return (KindEnum) KINDS.get(kind);
    }

    public String toString() { return _kind; }
}
            </code-panel>

        <p>At your Product class you may want to have a property that tells you what kind of
        computer equipment a product is of.</p>

            <code-panel>
public class Product {
    private int         _id;
    private String      _name;
    private KindEnum    _kind;
    
    public Product() { }
    
    public int getId() { return _id; }
    public void setId(int id) { _id = id; }

    public String getName() { return _name; }
    public void setName(String name) { _name = name; }

    public KindEnum getKind() { return _kind; }
    public void setKind(KindEnum kind) { _kind = kind; }
}
            </code-panel>
            
    </section>

    <section title="Steps">

            <p>Your mapping for the Product class should be:</p>

            <code-panel>
&lt;class name="Product" identity="id"&gt;
  &lt;description&gt;Product with kind enum&lt;/description&gt;
  &lt;map-to table="enum_prod"/&gt;
  &lt;field name="id" type="integer"&gt;
    &lt;sql name="id" type="integer"/&gt;
  &lt;/field&gt;
  &lt;field name="name" type="string"&gt;
    &lt;sql name="name" type="char"/&gt;
  &lt;/field&gt;
  &lt;field name="kind" type="KindEnum"&gt;
    &lt;sql name="kind" type="char"/&gt;
  &lt;/field&gt;
&lt;/class&gt;
            </code-panel>

    </section>
    
    <section title="Tips">

        <ul>
           <li>To add this new feature we added an additional check when searching for field types.
           Like before Castor first searches for know types and thereafter for a mapping for
           the class you specified as type. If both of them do not match it now checks if the
           class specified as type is available at classpath and has a static valueOf(String)
           method. Only if all of this conditions are met it will be viewed as a valid mapping.</li>
        </ul>    
        
    </section>

    </body>
</document>