java - Exception when unmarshalling XML with XStream -
i have created converter
javafx.scene.shape.path
bèzier-path. convert path elements of type moveto
, cubiccurveto
, have converters:
public class movetoconverter implements converter { @override public void marshal(object source, hierarchicalstreamwriter writer, marshallingcontext context) { writer.startnode("move-to"); moveto start = (moveto) source; writer.addattribute("startx", string.valueof(start.getx())); writer.addattribute("starty", string.valueof(start.gety())); writer.endnode(); } @override public object unmarshal(hierarchicalstreamreader reader, unmarshallingcontext context) { reader.movedown(); moveto moveto = new moveto(); moveto.setx(double.valueof(reader.getattribute("startx"))); moveto.sety(double.valueof(reader.getattribute("starty"))); reader.moveup(); return moveto; } @override public boolean canconvert(class type) { return moveto.class.equals(type); } } public class cubiccurvetoconverter implements converter { @override public void marshal(object source, hierarchicalstreamwriter writer, marshallingcontext context) { cubiccurveto curveto = (cubiccurveto) source; writer.startnode("cubic-curve-to"); writer.addattribute("controlx1", string.valueof(curveto.getcontrolx1())); writer.addattribute("controly1", string.valueof(curveto.getcontroly1())); writer.addattribute("controlx2", string.valueof(curveto.getcontrolx2())); writer.addattribute("controly2", string.valueof(curveto.getcontroly2())); writer.addattribute("x", string.valueof(curveto.getx())); writer.addattribute("y", string.valueof(curveto.gety())); writer.endnode(); } @override public object unmarshal(hierarchicalstreamreader reader, unmarshallingcontext context) { reader.movedown(); cubiccurveto curveto = new cubiccurveto(); curveto.setx(double.valueof(reader.getattribute("x"))); curveto.sety(double.valueof(reader.getattribute("y"))); curveto.setcontrolx1(double.valueof(reader.getattribute("controlx1"))); curveto.setcontroly1(double.valueof(reader.getattribute("controly1"))); curveto.setcontrolx2(double.valueof(reader.getattribute("controlx2"))); curveto.setcontroly2(double.valueof(reader.getattribute("controly2"))); reader.moveup(); return curveto; } @override public boolean canconvert(class type) { return cubiccurveto.class.equals(type); } } public class pathconverter implements converter { @override public void marshal(object o, hierarchicalstreamwriter writer, marshallingcontext marshallingcontext) { path path = (path) o; list<pathelement> elements = path.getelements(); writer.startnode("bezier-path"); writer.addattribute("count", string.valueof(elements.size())); moveto start = (moveto) elements.get(0); marshallingcontext.convertanother(start); // serialize start (int = 1; < elements.size(); i++) { cubiccurveto curveto = (cubiccurveto) elements.get(i); marshallingcontext.convertanother(curveto); } writer.endnode(); } @override public object unmarshal(hierarchicalstreamreader reader, unmarshallingcontext context) { reader.movedown(); path path = new path(); path.setstrokewidth(2); path.setstroke(color.red); int nbelements = integer.parseint(reader.getattribute("count")); moveto moveto = (moveto) context.convertanother(path, moveto.class); path.getelements().add(moveto); (int = 1; < nbelements; i++) { cubiccurveto curveto = (cubiccurveto) context.convertanother(path, cubiccurveto.class); path.getelements().add(curveto); system.out.println("added curve to: "+curveto); } reader.moveup(); return path; } @override public boolean canconvert(class aclass) { return path.class.equals(aclass); } }
and have test code:
path path = new path(); path.getelements().add(new moveto(2, 1)); path.getelements().add(new cubiccurveto(1, 2, 3, 4, 5, 6)); path.getelements().add(new cubiccurveto(11, 12, 13, 14, 15, 16)); path.getelements().add(new cubiccurveto(21, 22, 23, 24, 25, 26)); path.getelements().add(new cubiccurveto(31, 32, 33, 34, 35, 36)); path.getelements().add(new cubiccurveto(41, 42, 43, 44, 45, 46)); xstream xstream = new xstream(); xstream.registerconverter(converter); xstream.registerconverter(new movetoconverter()); xstream.registerconverter(new cubiccurvetoconverter()); file f = file.createtempfile(getclass().getname(), ".xml"); outputstream os = new fileoutputstream(f); xstream.toxml(path, os); object result = xstream.fromxml(f); assertequals(path.tostring(), result.tostring()); f.delete();
the file created when mashalling path looks this, want:
<javafx.scene.shape.path> <bezier-path count="6"> <move-to startx="2.0" starty="1.0"/> <cubic-curve-to controlx1="1.0" controly1="2.0" controlx2="3.0" controly2="4.0" x="5.0" y="6.0"/> <cubic-curve-to controlx1="11.0" controly1="12.0" controlx2="13.0" controly2="14.0" x="15.0" y="16.0"/> <cubic-curve-to controlx1="21.0" controly1="22.0" controlx2="23.0" controly2="24.0" x="25.0" y="26.0"/> <cubic-curve-to controlx1="31.0" controly1="32.0" controlx2="33.0" controly2="34.0" x="35.0" y="36.0"/> <cubic-curve-to controlx1="41.0" controly1="42.0" controlx2="43.0" controly2="44.0" x="45.0" y="46.0"/> </bezier-path> </javafx.scene.shape.path>
however when unmarshalling xml run exception:
com.thoughtworks.xstream.converters.conversionexception: start_tag can have attributes end_tag seen ...<bezier-path count="6">\n <move-to startx="2.0" starty="1.0"/>... @3:41 : start_tag can have attributes end_tag seen ...<bezier-path count="6">\n <move-to startx="2.0" starty="1.0"/>... @3:41 ---- debugging information ---- message : start_tag can have attributes end_tag seen ...<bezier-path count="6">\n <move-to startx="2.0" starty="1.0"/>... @3:41 cause-exception : java.lang.indexoutofboundsexception cause-message : start_tag can have attributes end_tag seen ...<bezier-path count="6">\n <move-to startx="2.0" starty="1.0"/>... @3:41 class : javafx.scene.shape.path required-type : javafx.scene.shape.path converter-type : ch.sahits.game.openpatrician.persistence.converter.pathconverter path : /javafx.scene.shape.path/bezier-path line number : 3 version : 1.4.8 ------------------------------- @ com.thoughtworks.xstream.core.treeunmarshaller.convert(treeunmarshaller.java:79) @ com.thoughtworks.xstream.core.abstractreferenceunmarshaller.convert(abstractreferenceunmarshaller.java:65) @ com.thoughtworks.xstream.core.treeunmarshaller.convertanother(treeunmarshaller.java:66) @ com.thoughtworks.xstream.core.treeunmarshaller.convertanother(treeunmarshaller.java:50) @ com.thoughtworks.xstream.core.treeunmarshaller.start(treeunmarshaller.java:134) @ com.thoughtworks.xstream.core.abstracttreemarshallingstrategy.unmarshal(abstracttreemarshallingstrategy.java:32) @ com.thoughtworks.xstream.xstream.unmarshal(xstream.java:1206) @ com.thoughtworks.xstream.xstream.unmarshal(xstream.java:1190) @ com.thoughtworks.xstream.xstream.fromxml(xstream.java:1154) @ com.thoughtworks.xstream.xstream.fromxml(xstream.java:1096) @ ch.sahits.game.openpatrician.persistence.converter.pathconvertertest.shouldconvertobjecttoxmlandback(pathconvertertest.java:49) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ java.lang.reflect.method.invoke(method.java:498) @ org.junit.runners.model.frameworkmethod$1.runreflectivecall(frameworkmethod.java:50) @ org.junit.internal.runners.model.reflectivecallable.run(reflectivecallable.java:12) @ org.junit.runners.model.frameworkmethod.invokeexplosively(frameworkmethod.java:47) @ org.junit.internal.runners.statements.invokemethod.evaluate(invokemethod.java:17) @ org.junit.runners.parentrunner.runleaf(parentrunner.java:325) @ org.junit.runners.blockjunit4classrunner.runchild(blockjunit4classrunner.java:78) @ org.junit.runners.blockjunit4classrunner.runchild(blockjunit4classrunner.java:57) @ org.junit.runners.parentrunner$3.run(parentrunner.java:290) @ org.junit.runners.parentrunner$1.schedule(parentrunner.java:71) @ org.junit.runners.parentrunner.runchildren(parentrunner.java:288) @ org.junit.runners.parentrunner.access$000(parentrunner.java:58) @ org.junit.runners.parentrunner$2.evaluate(parentrunner.java:268) @ org.junit.runners.parentrunner.run(parentrunner.java:363) @ org.junit.runner.junitcore.run(junitcore.java:137) @ com.intellij.junit4.junit4ideatestrunner.startrunnerwithargs(junit4ideatestrunner.java:69) @ com.intellij.rt.execution.junit.junitstarter.preparestreamsandstart(junitstarter.java:234) @ com.intellij.rt.execution.junit.junitstarter.main(junitstarter.java:74) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ java.lang.reflect.method.invoke(method.java:498) @ com.intellij.rt.execution.application.appmain.main(appmain.java:144) caused by: java.lang.indexoutofboundsexception: start_tag can have attributes end_tag seen ...<bezier-path count="6">\n <move-to startx="2.0" starty="1.0"/>... @3:41 @ org.xmlpull.mxp1.mxparser.getattributevalue(mxparser.java:927) @ com.thoughtworks.xstream.io.xml.xppreader.getattribute(xppreader.java:139) @ com.thoughtworks.xstream.io.readerwrapper.getattribute(readerwrapper.java:52) @ com.thoughtworks.xstream.core.abstractreferenceunmarshaller.convert(abstractreferenceunmarshaller.java:53) @ com.thoughtworks.xstream.core.treeunmarshaller.convertanother(treeunmarshaller.java:66) @ com.thoughtworks.xstream.core.treeunmarshaller.convertanother(treeunmarshaller.java:50) @ ch.sahits.game.openpatrician.persistence.converter.pathconverter.unmarshal(pathconverter.java:52) @ com.thoughtworks.xstream.core.treeunmarshaller.convert(treeunmarshaller.java:72) ... 36 more
the line 52 in pathconverter points line (first call in for-loop):
cubiccurveto curveto = (cubiccurveto) context.convertanother(path, cubiccurveto.class);
my guess problem has movedown
, moveup
method on unmarshal
method, reader still in state expects end node of move-to
. other 2 converters have tests, run fine, problem seems lie in combination , call context.convertanother
.
i know thinking in creating converter went wrong , how can solved.
you're operating on stream. if next step not read tag's value. may cause error
try:
reader.movedown(); path path = new path(); path.setstrokewidth(2); path.setstroke(color.red); int nbelements = integer.parseint(reader.getattribute("count")); moveto moveto = (moveto) context.convertanother(path, moveto.class); path.getelements().add(moveto); reader.moveup(); (int = 1; < nbelements; i++) { reader.movedown(); cubiccurveto curveto = (cubiccurveto) context.convertanother(path, cubiccurveto.class); path.getelements().add(curveto); system.out.println("added curve to: "+curveto); reader.moveup(); } return path;
Comments
Post a Comment