MOXy - How to map multiple nodes with the same path? [message #487853] |
Thu, 24 September 2009 15:08 |
Matti Hansson Messages: 68 Registered: July 2009 |
Member |
|
|
Hi!
I have a value which I map to two fields:
MyClass { <MyXML>
value; <--> <valuePartA>ABC</valuePartA>
} <valuePartB>123</valuePartB>
</MyXML>
Using a transformation mapping, this is no problem. The trouble comes from the fact that the node <valuePartB> may appear many times in <MyXML>, and I need all "B-values" to create the value in MyClass.
Is this at all possible? Maybe by having an intermediary class with a "valueA" and a list of "valueB"s, but how would the transformer get hold of the intermediary instance?
Thanks!
[Updated on: Thu, 24 September 2009 15:21] Report message to a moderator
|
|
|
Re: MOXy - How to map multiple nodes with the same path? [message #488885 is a reply to message #487853] |
Wed, 30 September 2009 15:33 |
|
Hello Matti,
For situations like this I recommend using a converter instead of a transformation mapping. With this approach you use an intermediate object as you describe.
I am assuming your domain object looks something like the following:
public class MyObject {
private String[] value;
...
}
An intermediate object could be created that looks like:
public class IntermediateValue {
private String partA;
private List<String> partB;
...
When mapping the value property on MyObject I would use an XMLCompositeObjectMapping, setting the reference class to be IntermediateValue.class (instead of the actual type of the value property).
XMLCompositeObjectMapping valueMapping = new XMLCompositeObjectMapping();
valueMapping.setReferenceClass(IntermediateValue.class);
valueMapping.setAttributeName("value");
valueMapping.setXPath("value");
valueMapping.setConverter(new ValueConverter());
xmlDescriptor.addMapping(valueMapping);
The ValueConvter class would look something like the following:
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;
public class ValueConverter implements Converter {
public void initialize(DatabaseMapping mapping, Session session) {
}
public Object convertObjectValueToDataValue(Object objectValue, Session session) {
String[] stringArray = (String[]) objectValue;
IntermediateValue intermediateValue = new IntermediateValue();
intermediateValue.setPartA(stringArray[0]);
for(int x=1; x<stringArray.length; x++) {
intermediateValue.getPartB().add(stringArray[x]);
}
return intermediateValue;
}
public Object convertDataValueToObjectValue(Object dataValue, Session session) {
IntermediateValue intermediateValue = (IntermediateValue) dataValue;
String[] stringArray = new String[intermediateValue.getPartB().size() + 1];
stringArray[0] = intermediateValue.getPartA();
for(int x=0; x<intermediateValue.getPartB().size(); x++) {
stringArray[x + 1] = intermediateValue.getPartB().get(x);
}
return stringArray;
}
public boolean isMutable() {
return true;
}
}
This would allow you to produce XML that looks like the following:
<MyXML>
<value>
<valuePartA>ABC</valuePartA>
<valuePartB>123</valuePartB>
<valuePartB>456</valuePartB>
</value>
</MyXML>
If you want to eliminate the "value" node then the XPath on the XMLCompositeObjectMapping should be changed to "." instead of "value". It appears as though there is a bug in EclipesLink 1.2 where conveters are not called on XMLCompositeObjectMappings when the XPath is ".". This bug has been fixed in the EclipseLink 2.0 stream.
-Blaise
[Updated on: Fri, 16 October 2009 20:52] Report message to a moderator
|
|
|
Re: MOXy - How to map multiple nodes with the same path? [message #488938 is a reply to message #488885] |
Wed, 30 September 2009 18:56 |
Matti Hansson Messages: 68 Registered: July 2009 |
Member |
|
|
Thank you so much for your help, Blaise!
And to repay you: a bug report
My case got a little more complicated, so I decided to use an XMLChoiceObjectMapping for the value instead. Going from XML to Java proved to be a cinch but when going the other way the converter never ran.
I did some debugging, and it seems like the mapping is looking for which XMLField is associated with the object, but it doesn't take into account that the object might have to be converted back first, so no XMLField is found and nothing is written.
I understand the object may be converted to any class, so it's impossible to tell which converter to use until it's been converted. Because of this catch 22 the behaviour might not be a bug, in which case I apologize.
I managed to solve my problem with an XMLAnyObjectMapping, so it doesn't bother me.
Anyway, thanks again!
/Matti
|
|
|
|
Powered by
FUDForum. Page generated in 0.02710 seconds