我有以下 Java 对象层次结构:
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) {
// ...
}
}
用户可以通过在 XML 中定义它们来创建ConstantFunction
和实例,如下所示:LinearFunction
<myapp>
<function type="ConstantFunction>
<!-- ... -->
</function>
<function type="LinearFunction>
<!-- ... -->
</function>
</myapp>
我正在使用 XStream 将用户定义的 XML OX 映射到 Java POJO。我目前正在尝试XStream
使用别名配置映射器,以便它知道要绑定到function
元素的 Java 类:
XStream oxmapper = new XStream();
oxmapper.alias("myapp", MyApp.class);
oxmapper.alias("function", ???);
问题是,我需要使用以下逻辑配置 XStream: *if function/type
is ConstantFunction
, then use oxmapper.alias("function", ConstantFunction.class)
; 但如果它的值为LinearFunction
,则使用oxmapper.alias("function", LinearFunction.class)
。
问题是,我不认为 XStream API 提供了一种方法来按照我需要的方式检查 XML 以实现此逻辑。如果我不正确,请指出正确的方向!
如果我是正确的,那么我能想到的唯一解决方案就是有一个非常讨厌的“大杂烩”类,它形成了所有Function
混凝土的联合,如下所示:
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;
}
}
在 OX-mapper 配置中:
oxampper.alias("function", FunctionFactory.class);
oxmapper.aliasField("function", "type", "concreteClass");
现在,每次我将 XML 实例读入MyApp
实例时,我都需要更正转换:
XStream oxmapper = getConfiguredMapper();
MyApp app = oxmapper.fromXml("<myapp>...</myapp>");
FunctionFactory factory = app.getFunction();
Function concretion = factory.getConcreteClass();
app.setFunction(concretion);
这是我能做的唯一解决方法,但感觉真的很讨厌,我必须相信有更好的方法来做到这一点。提前致谢!