Castor Hashtable polymorphism

127 Views Asked by At

Good Day

I am attempting to use castor to construct a HashTable that has multiple implementations of an abstract class. here is the parent "config"

<class name="com.Config">
    <map-to xml="config" />
    <field name="rulesMap" collection="hashtable">
        <bind-xml  auto-naming="deriveByClass"  >
            <class name="org.exolab.castor.mapping.MapItem">
                <field name="key" type="java.lang.String">
                    <bind-xml name="name" node="attribute" />
                </field>
                <field name="value" type=com.Rule">

                </field>
            </class>
        </bind-xml>
    </field>
</class>

'com.Rule' is an Abstract Class and at the end of the day i would like an xml struct that looks like this

<config>
<rule-impl1 name="ruleType1Instance1" ruleField="field"  />
    <rule-impl2 name="ruleType2Instance2" ruleField="field" ruleImpl2Field1="..." />
</config>
1

There are 1 best solutions below

0
On

I'm not sure there is enough detail or a question that is well formed here to give an accurate answer, but I was doing something pretty similar and ran into some roadblocks. Thought I'd provide my 2 cents. I'm not as familiar with Castor as I am some other XML frameworks and in my case Castor is doing it's automatic marshalling/unmarshalling instead of us manually writing the code to decide when we want it to be done. If we were manually doing that piece I thought we would have been able to make decisions to unmarshall to specific classes that extend the abstract class.

With all my disclaimers out of the way, what you could do.

**If you can add a field to the request/response then create something like this:

public class RuleContainer {
 private RuleType ruleType;  // possibly build enum or other non-java equivalent
 private RuleImpl1 ruleImpl1;
 private RuleImpl2 ruleImpl2;
 private RuleImpl...N ruleImpl...N;
 // getters & setters, etc
}

Then the value of your table is changed to

<field name="value" type="com.RuleContainer"></field>

and include your mapping of the RuleContainer

 <class name="com.RuleContainer">
   <field name="ruleType" type="com.RuleType"
   <field name="ruleImpl1" type="com.RuleImpl1">
   <field name="ruleImpl2" type="com.RuleImpl2">
   <field name="ruleImpl...N" type="com.RuleImpl...N">
 </class>

also include mappings of each implementation whatever those may look like. In my case I've broken each implementation mapping out into a separate file and used the

<include href="" /> 

tag to include those extraneous mappings in the parent file.

All of this sets you up to use that RuleType field to know which rule in the RuleContainer is valid (the rest will be null as the Castor default is required="false"). The logic to work with each implementation of a Rule is simple to write from there. Hope this helps.