Hi Keith,
in the example which u've given instead of using a different field
handler, couldn't we just add get and set methods in the Foo class for
getting and setting the Color variable? e.g we could add getColorAsString()
and setColor(String color). I think adding a new field handler class is an
overkill for this purpose... if i'm missing some potential scenario's in
which this field handler would be useful, don't forget to point them out to
me.
e.g i had a class in which i had to set the values of the member variables,
but i didn't want to add any get/set methods to that class. in this case a
field handler would be useful. but if i have a huge number of such fields, i
would still opt for adding get/set methods to the class instead of defining
a number of field handler classes.
-----Original Message-----
From: Keith Visco [mailto:[EMAIL PROTECTED]]
Sent: Thursday, December 06, 2001 6:54 AM
To: [EMAIL PROTECTED]
Subject: Re: [castor-dev] mapping user-defined data types
Max Foxell wrote:
>
> Jeff,
>
> we have the same problem with Enum classes. In the database we are
> storing a single selection of an enumeration as a string but in Java
> we want the String to be retrieved from the database as an instance of
> our Enum class. e.g.
>
> In database we store the string "RED", but we want to map that to the
> "RED" instance of the following enum class (i.e. map to
> ColoursEnum.RED):
>
> public class ColoursEnum
> {
> private String name;
> private Colours(String name) { this.name = name; }
> public String toString() { return name; }
> public static final ColoursEnum RED = new ColoursEnum("RED");
> public static final ColoursEnum GREEN = new ColoursEnum("GREEN");
> public static final ColoursEnum BLUE = new ColoursEnum("BLUE");
> }
>
> Castor can already perform mappings between simple database types to
> classes (where the database types indicate the identity of an object).
> It would be great to hook into this mechanism using the mapping file
> (e.g. identify a "converter" class that implements a particular
> interface to perform the conversion from/to database type to/from Java
> class). A mechanism like this could significantly improve Castor's
> mapping strengths (and reduce the impedance mismatch further). I'm
> sure converters of this sort could be put to all sorts of good uses.
> Maybe one of the Castor developers (Thomas?) could indicate whether
> this functionality is on their "to do" list or even in the next
> release ;-)?
>
This should now work in the CVS (at least it does for Castor XML). I
have added the ever powerful handler attribute to the field element of a
mapping file. This enables you to implement your own FieldHandler and
use it instead of the automatically created one from Castor.
I recommend using type="string" as follows in this simple example
--- Mapping File ---
<?xml version="1.0"?>
<mapping>
<class name="my.package.Foo">
<field name="color" type="string"
handler="my.package.ColorHandler"/>
</class>
</mapping>
--- Special FieldHandler ---
package my.package;
import org.exolab.castor.mapping.FieldHandler;
import org.exolab.castor.mapping.ValidityException;
/**
* The FieldHandler for the "color" field of the Foo class.
**/
public class ColorHandler
implements org.exolab.castor.mapping.FieldHandler
{
/**
* Creates a new ColorHandler for the Foo class
**/
public ColorHandler() {
super();
}
/**
* Returns the value of the field from the object.
*
* @param object The object
* @return The value of the field
* @throws IllegalStateException The Java object has changed and
* is no longer supported by this handler, or the handler is not
* compatiable with the Java object
*/
public Object getValue( Object object )
throws IllegalStateException
{
Color color = ((Foo)object).getColor();
if (color == null) return null;
return color.toString();
}
/**
* Sets the value of the field on the object.
*
* @param object The object
* @param value The new value
* @throws IllegalStateException The Java object has changed and
* is no longer supported by this handler, or the handler is not
* compatiable with the Java object
* @thorws IllegalArgumentException The value passed is not of
* a supported type
*/
public void setValue( Object object, Object value )
throws IllegalStateException, IllegalArgumentException
{
Color color = Color.valueOf((String)value);
((Foo)object).setColor(color);
}
/**
* Sets the value of the field to a default value.
* <p>
* Reference fields are set to null, primitive fields are set to
* their default value, collection fields are emptied of all
* elements.
*
* @param object The object
* @throws IllegalStateException The Java object has changed and
* is no longer supported by this handler, or the handler is not
* compatiable with the Java object
*/
public void resetValue( Object object )
throws IllegalStateException, IllegalArgumentException
{
((Foo)object).setColor((Color)null);
}
/**
* @deprecated No longer supported
*/
public void checkValidity( Object object )
throws ValidityException, IllegalStateException
{
//-- add validation check if desired
}
/**
* Creates a new instance of the object described by this field.
*
* @param parent The object for which the field is created
* @return A new instance of the field's value
* @throws IllegalStateException This field is a simple type and
* cannot be instantiated
*/
public Object newInstance( Object parent )
throws IllegalStateException
{
//-- Since it's marked as a string...just return null,
//-- it's not needed.
return null;
}
}
--- Foo.java ---
package my.package;
public class Foo {
private Color _color = null;
public Foo() {
super();
}
public Color getColor() {
return _color;
}
public void setColor(Color color) {
_color = color;
}
}
--- Color.java ---
/*
* This class was automatically generated with
* <a href="http://castor.exolab.org">Castor 0.9.3</a>, using an
* XML Schema.
* $Id$
*/
package my.package;
//---------------------------------/
//- Imported classes and packages -/
//---------------------------------/
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import org.exolab.castor.xml.*;
/**
*
* @version $Revision$ $Date$
**/
public class Color implements java.io.Serializable {
//--------------------------/
//- Class/Member Variables -/
//--------------------------/
/**
* The red type
**/
public static final int RED_TYPE = 0;
/**
* The instance of the red type
**/
public static final Color RED = new Color(RED_TYPE, "red");
/**
* The green type
**/
public static final int GREEN_TYPE = 1;
/**
* The instance of the green type
**/
public static final Color GREEN = new Color(GREEN_TYPE, "green");
/**
* The blue type
**/
public static final int BLUE_TYPE = 2;
/**
* The instance of the blue type
**/
public static final Color BLUE = new Color(BLUE_TYPE, "blue");
private static java.util.Hashtable _memberTable = init();
private int type = -1;
private java.lang.String stringValue = null;
//----------------/
//- Constructors -/
//----------------/
private Color(int type, java.lang.String value) {
super();
this.type = type;
this.stringValue = value;
} //-- test.types.Color(int, java.lang.String)
//-----------/
//- Methods -/
//-----------/
/**
* Returns an enumeration of all possible instances of Color
**/
public static java.util.Enumeration enumerate()
{
return _memberTable.elements();
} //-- java.util.Enumeration enumerate()
/**
* Returns the type of this Color
**/
public int getType()
{
return this.type;
} //-- int getType()
/**
**/
private static java.util.Hashtable init()
{
Hashtable members = new Hashtable();
members.put("red", RED);
members.put("green", GREEN);
members.put("blue", BLUE);
return members;
} //-- java.util.Hashtable init()
/**
* Returns the String representation of this Color
**/
public java.lang.String toString()
{
return this.stringValue;
} //-- java.lang.String toString()
/**
* Returns a new Color based on the given String value.
* @param string
**/
public static Color valueOf(java.lang.String string)
{
Object obj = null;
if (string != null) obj = _memberTable.get(string);
if (obj == null) {
String err = "'" + string + "' is not a valid Color";
throw new IllegalArgumentException(err);
}
return (Color) obj;
} //-- test.types.Color valueOf(java.lang.String)
}
---------
Hope that solves the problem for you...
--Keith
>
> Jeff Hoare wrote:
>
> > Hi,
> > Is there anyway to map user defined data types in Castor. We are
> > using a guio
> > framwork that defines its own set of java types. In may cases these
> > are just
> > wrappers for some base Java Class, for example TextString is a
> > wrapper for a
> > String, and the "name" property returns one of these classes.
> > We don't want to have to store these seperatly in tables, but as
> > column
> > attributes of the class itself.
> > I can add specific getters/setters on the actual classes that return
> > standard
> > java representations, but it would be good not to have to have these
> > xtra's.
> > So :-)
> > Is it possible to map such classes to standard castor
> > representations
> > or
> > Does this require an extension of the castor framework?
> >
> > Jeff
> >
> > -----------------------------------------------------------
> > If you wish to unsubscribe from this mailing, send mail to
> > [EMAIL PROTECTED] with a subject of:
> > unsubscribe castor-dev
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev
-----------------------------------------------------------
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
unsubscribe castor-dev