21
21
22
22
import org .apache .axiom .om .OMElement ;
23
23
import org .apache .axiom .om .OMXMLBuilderFactory ;
24
- import org .apache .axiom .om .OMXMLParserWrapper ;
25
24
import org .apache .xmlbeans .XmlObject ;
26
25
import org .mozilla .javascript .Context ;
27
26
import org .mozilla .javascript .Scriptable ;
33
32
* JSObjectConvertor converts between OMElements and JavaScript E4X XML objects
34
33
*/
35
34
public class JSOMElementConvertor extends DefaultOMElementConvertor {
36
-
37
- protected Scriptable scope ;
38
-
39
- public JSOMElementConvertor () {
40
- Context cx = Context .enter ();
41
- try {
42
- this .scope = cx .initStandardObjects ();
43
- } finally {
44
- Context .exit ();
45
- }
46
- }
47
-
48
35
public Object toScript (OMElement o ) {
49
36
XmlObject xml ;
50
37
try {
@@ -55,30 +42,65 @@ public Object toScript(OMElement o) {
55
42
56
43
Context cx = Context .enter ();
57
44
try {
45
+ // Enable E4X support
46
+ cx .setLanguageVersion (Context .VERSION_1_6 );
47
+ Scriptable tempScope = cx .initStandardObjects ();
58
48
59
- Object wrappedXML = cx .getWrapFactory ().wrap (cx , scope , xml , XmlObject .class );
60
- Scriptable jsXML = cx .newObject (scope , "XML" , new Object [] { wrappedXML });
61
-
62
- return jsXML ;
63
-
49
+ // Wrap the XmlObject directly
50
+ return cx .getWrapFactory ().wrap (cx , tempScope , xml , XmlObject .class );
64
51
} finally {
65
52
Context .exit ();
66
53
}
67
54
}
68
55
69
56
public OMElement fromScript (Object o ) {
70
- if (!(o instanceof XMLObject )) {
57
+ if (!(o instanceof XMLObject ) && !( o instanceof Wrapper ) ) {
71
58
return super .fromScript (o );
72
59
}
73
60
74
- // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost. See Mozilla bugzilla 361722
75
- Scriptable jsXML = (Scriptable ) ScriptableObject .callMethod ((Scriptable ) o , "copy" , new Object [0 ]);
76
- Wrapper wrapper = (Wrapper ) ScriptableObject .callMethod ((XMLObject )jsXML , "getXmlObject" , new Object [0 ]);
77
- XmlObject xmlObject = (XmlObject )wrapper .unwrap ();
78
- OMXMLParserWrapper builder = OMXMLBuilderFactory .createOMBuilder (xmlObject .newInputStream ());
79
- OMElement omElement = builder .getDocumentElement ();
61
+ try {
62
+ XmlObject xmlObject = null ;
63
+
64
+ // Handle wrapped XmlObject
65
+ if (o instanceof Wrapper ) {
66
+ Object unwrapped = ((Wrapper ) o ).unwrap ();
67
+ if (unwrapped instanceof XmlObject ) {
68
+ xmlObject = (XmlObject ) unwrapped ;
69
+ }
70
+ }
80
71
81
- return omElement ;
82
- }
72
+ // If we have an XMLObject but not a wrapped XmlObject, try the old approach
73
+ if (xmlObject == null && o instanceof XMLObject ) {
74
+ // TODO: E4X Bug? Shouldn't need this copy, but without it the outer element gets lost. See Mozilla bugzilla 361722
75
+ XMLObject jsXML = (XMLObject ) ScriptableObject .callMethod ((XMLObject ) o , "copy" , new Object [0 ]);
76
+
77
+ // get proper XML representation from toXMLString()
78
+ String xmlString ;
79
+ try {
80
+ // Try toXMLString() method first
81
+ xmlString = (String ) ScriptableObject .callMethod (jsXML , "toXMLString" , new Object [0 ]);
82
+ } catch (Exception toXMLException ) {
83
+ // If toXMLString() doesn't work, try toString()
84
+ xmlString = jsXML .toString ();
85
+ }
83
86
87
+ // Remove extra whitespace to match expected format
88
+ String normalizedXML = xmlString .replaceAll (">\\ s+<" , "><" ).trim ();
89
+ return OMXMLBuilderFactory
90
+ .createOMBuilder (new java .io .StringReader (normalizedXML ))
91
+ .getDocumentElement ();
92
+ }
93
+
94
+ if (xmlObject != null ) {
95
+ return OMXMLBuilderFactory
96
+ .createOMBuilder (xmlObject .newInputStream ())
97
+ .getDocumentElement ();
98
+ } else {
99
+ throw new RuntimeException ("Unable to extract XmlObject from JavaScript object" );
100
+ }
101
+
102
+ } catch (Exception e ) {
103
+ throw new RuntimeException ("Failed to convert JavaScript XML to OMElement: " + e .getMessage (), e );
104
+ }
105
+ }
84
106
}
0 commit comments