"Yaldiz, Sunay" wrote:
> 
> Hello all,
> 
> I have a question about XML mapping.
> I have a class which looks like this:
> 
> public  class GlobalEnvironment{
>         public double accelerationOfGravity ;
>         public double densityWater ;
>         public double densityAir ;
>         public double viscosityWater;
>         public double temperatureWater;
>         public double salinityWater ;
> 
> }
> 
> I want the XML structure for GlobalEnvironment instances as follows:
> 
> <GlobalEnvironment>
>         <Water>
>                 <Viscosity>34</Viscosity>
>                 <Density>1.0</Density>
>                 <Temperature>100</Temperature>
>                 <Salinity>34</Salinity>
>         </Water>
>         <Gravity>10.0</Gravity>
>         <Air>
>         <Density>0.00123</Density>
>          </Air>
> </GlobalEnvironment>
> 
> I mean I want that the fields ...Water in the class are residing under
> element <Water>, and respectively for air.
> Of course it is possible to create this XML structure by changing the
> class definition a little bit, but what I want is not this.  Is it
> possible to map this class definition to such an XML structure? Or is it
> must for me either to change the XML representation of the
> GlobalEnvironment class or change the GlobalEnvironment and add some
> classes Water, Air ...?
> 
> I tried using location attribute setting location="Water" for mapping of
> fields densityWater,viscosityWater,temperatureWater and salinityWater
> but it did not give the result I wanted. The mapping packed the fields
> in different "Water" elements.

This is a known issue with the location attribute, which I am working
on.

Another solution is to use some Wrapper classes. You don't have to
change your existing model at all, you can keep using your existing
model, but a few Wrapper classes (Air, Water) that are returned by
special field handlers would give you the result you're looking for.

For example:

public class Air {

   private double density;

   /**
    * Default constructor (required by Castor)
    */
   public Air() {
      super();
   }

   /**
    * A Convenience constructor that initializes
    * this Air instance with the given GlobalEnvironment
    */
   public Air(GlobalEnvironment ge) {
      density = ge.densityAir;
   }

   public double getDensity() {
      return density;
   }
   public void setDensity(double density) {
       this.density = density;     
   }
}

Then you could use a custom org.exolab.castor.mapping.FieldHandler (see
also AbstractFieldHandler or GeneralizedFieldHandler), whose getValue
would return
the proper Air, or Water wrapper class, and the setValue would do the
reverse:

public class AirFieldHandler extends AbstractFieldHandler {

...
    public Object getValue(Object target) {
        return new Air((GlobalEnvironment)target);
    }

...

    public void setValue(Object target, Object value) {
        GlobalEnvironment ge = (GlobalEnvironment)target;
        Air air = (Air)value;
        ge.densityAir = air.getDensity();
    }

}

Your mapping file would then look like:

<class name="com.amce.GlobalEnvironment">
   <field name="air" type="com.acme.Air"
handler="com.acme.AirFieldHandler"/>
   <field name="air" type="com.acme.Water"
handler="com.acme.WaterFieldHandler"/>
</class>


So you don't have to change your GlobalEnvironment class to get the
desired result, but it is a bit more work. Hopefully I'll have the
location attribute code will be cleaned up soon.

Hope that helps,

--Keith

----------------------------------------------------------- 
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
        unsubscribe castor-dev

Reply via email to