I have the following Java object hierarchy:
public interface Function {
public void calculate(long t);
}
public class ConstantFunction implements Function {
private double constant;
@Override
public void calculate(long t) {
// ...
}
}
public class LinearFunction implements Function {
private double slope;
private double yIntercept;
@Override
public void calculate(long t) {
// ...
}
}
Users can create ConstantFunction
and LinearFunction
instances by defining them inside XML like so:
<myapp>
<function type="ConstantFunction>
<!-- ... -->
</function>
<function type="LinearFunction>
<!-- ... -->
</function>
</myapp>
I am using XStream to OX-map the user-defined XML into Java POJOs. I'm currently trying to configure the XStream
mapper with aliases so that it knows what Java class to bind to the function
element:
XStream oxmapper = new XStream();
oxmapper.alias("myapp", MyApp.class);
oxmapper.alias("function", ???);
The problem is, I need to configure XStream with logic that says: *if function/type
is ConstantFunction
, then use oxmapper.alias("function", ConstantFunction.class)
; but if its value is LinearFunction
, then use oxmapper.alias("function", LinearFunction.class)
.
The problem is, I don't think XStream API gives provides a way to inspect the XML the way I need it to in order to implement this logic. If I am incorrect, please point me in the right direction!
If I am correct, then the only solution I can think of would be to have a really nasty "hodgepodge" class that forms a union of all the Function
concretions like so:
public class FunctionFactory implements Function {
private double constant;
private double slope;
private double yIntercept;
private Class<? extends Function> concreteClass;
@Override
public void calculate(long t) {
// Do nothing. This class is a workaround to limitations with XStream.
return;
}
}
In the OX-mapper config:
oxampper.alias("function", FunctionFactory.class);
oxmapper.aliasField("function", "type", "concreteClass");
Now, every time I read an XML instance into a MyApp
instance, I need to correct the conversion:
XStream oxmapper = getConfiguredMapper();
MyApp app = oxmapper.fromXml("<myapp>...</myapp>");
FunctionFactory factory = app.getFunction();
Function concretion = factory.getConcreteClass();
app.setFunction(concretion);
This is the only workaround I can cook up, but it feels really nasty, and I have to believe there's a better way to do this. Thanks in advance!
When you want to have custom behaviors in XStream, you should use Converters as described in Converter tutorial.