1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.support;
14
15 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
16 import com.eviware.soapui.support.types.StringToStringMap;
17 import com.eviware.soapui.support.xml.XmlUtils;
18 import org.apache.xmlbeans.XmlCursor;
19 import org.apache.xmlbeans.XmlException;
20 import org.apache.xmlbeans.XmlObject;
21 import org.w3c.dom.Node;
22
23 import java.util.Collection;
24 import java.util.Map;
25 import java.util.Set;
26
27 public class XmlHolder implements Map<String, Object>
28 {
29 private XmlObject xmlObject;
30 private StringToStringMap declaredNamespaces;
31 private PropertyExpansionContext context;
32 private String propertyRef;
33
34 public XmlHolder( String xml ) throws XmlException
35 {
36 xmlObject = XmlObject.Factory.parse( xml );
37 }
38
39 public XmlHolder( Node node ) throws XmlException
40 {
41 xmlObject = XmlObject.Factory.parse( node );
42 }
43
44 public XmlHolder( XmlObject xmlObject ) throws XmlException
45 {
46 this.xmlObject = xmlObject;
47 }
48
49 public XmlHolder( PropertyExpansionContext context, String propertyRef ) throws XmlException
50 {
51 this( context.getProperty( propertyRef ).toString() );
52
53 this.context = context;
54 this.propertyRef = propertyRef;
55 }
56
57 public void updateProperty()
58 {
59 updateProperty( false );
60 }
61
62 public void updateProperty( boolean prettyPrint )
63 {
64 if( context != null && propertyRef != null )
65 {
66 context.setProperty( propertyRef, prettyPrint ? getPrettyXml() : getXml() );
67 }
68 }
69
70 public String getNodeValue( String xpath ) throws XmlException
71 {
72 return XmlUtils.selectFirstNodeValue( xmlObject, xpath );
73 }
74
75 public StringToStringMap getNamespaces()
76 {
77 if( declaredNamespaces == null )
78 declaredNamespaces = new StringToStringMap();
79
80 return declaredNamespaces;
81 }
82
83 public void declareNamespace( String prefix, String uri )
84 {
85 if( declaredNamespaces == null )
86 declaredNamespaces = new StringToStringMap();
87
88 declaredNamespaces.put( prefix, uri );
89 }
90
91 public String[] getNodeValues( String xpath ) throws XmlException
92 {
93 xpath = initXPathNamespaces( xpath );
94
95 return XmlUtils.selectNodeValues( xmlObject, xpath );
96 }
97
98 private String initXPathNamespaces( String xpath )
99 {
100 if( declaredNamespaces != null && !declaredNamespaces.isEmpty() )
101 {
102 for( String prefix : declaredNamespaces.keySet() )
103 {
104 xpath = "declare namespace " + prefix + "='" + declaredNamespaces.get( prefix ) + "';\n" + xpath;
105 }
106 }
107 else if( !xpath.trim().startsWith( "declare namespace" ) )
108 {
109 xpath = XmlUtils.declareXPathNamespaces( xmlObject ) + xpath;
110 }
111 return xpath;
112 }
113
114 public void setNodeValue( String xpath, Object value ) throws XmlException
115 {
116 xpath = initXPathNamespaces( xpath );
117
118 XmlCursor cursor = xmlObject.newCursor();
119 try
120 {
121 cursor.selectPath( xpath );
122
123 if( cursor.toNextSelection() )
124 {
125 XmlUtils.setNodeValue( cursor.getDomNode(), value == null ? null : value.toString() );
126 }
127 }
128 finally
129 {
130 cursor.dispose();
131 }
132 }
133
134 public XmlObject getXmlObject()
135 {
136 return xmlObject;
137 }
138
139 public Node getDomNode( String xpath ) throws XmlException
140 {
141 xpath = initXPathNamespaces( xpath );
142 return XmlUtils.selectFirstDomNode( xmlObject, xpath );
143 }
144
145 public Node[] getDomNodes( String xpath ) throws XmlException
146 {
147 xpath = initXPathNamespaces( xpath );
148 return XmlUtils.selectDomNodes( xmlObject, xpath );
149 }
150
151 public void removeDomNodes( String xpath ) throws XmlException
152 {
153 Node[] nodes = getDomNodes( xpath );
154 for( Node node : nodes )
155 {
156 node.getParentNode().removeChild( node );
157 }
158 }
159
160 public String getXml()
161 {
162 return xmlObject.xmlText();
163 }
164
165 public String getPrettyXml()
166 {
167 return XmlUtils.prettyPrintXml( xmlObject );
168 }
169
170 public void clear()
171 {
172 }
173
174 public boolean containsKey( Object key )
175 {
176 try
177 {
178 return getDomNode( key.toString() ) != null;
179 }
180 catch( XmlException e )
181 {
182 e.printStackTrace();
183 return false;
184 }
185 }
186
187 public boolean containsValue( Object value )
188 {
189 try
190 {
191 return getNodeValue( value.toString() ) != null;
192 }
193 catch( XmlException e )
194 {
195 e.printStackTrace();
196 return false;
197 }
198 }
199
200 public Set<java.util.Map.Entry<String, Object>> entrySet()
201 {
202 return null;
203 }
204
205 public Object get( Object key )
206 {
207 try
208 {
209 String str = key.toString();
210 if( str.equals( "prettyXml" ) )
211 return getPrettyXml();
212 else if( str.equals( "xmlObject" ) )
213 return getXmlObject();
214 else if( str.equals( "namespaces" ) )
215 return getNamespaces();
216 else if( str.equals( "xml" ) )
217 return getXml();
218
219 String[] nodeValues = getNodeValues( str );
220 return nodeValues != null && nodeValues.length == 1 ? nodeValues[0] : nodeValues;
221 }
222 catch( XmlException e )
223 {
224 e.printStackTrace();
225 return null;
226 }
227 }
228
229 public boolean isEmpty()
230 {
231 return false;
232 }
233
234 public Set<String> keySet()
235 {
236 return null;
237 }
238
239 public String put( String key, Object value )
240 {
241 try
242 {
243 String result = getNodeValue( key );
244 setNodeValue( key, value == null ? null : value.toString() );
245 return result;
246 }
247 catch( XmlException e )
248 {
249 e.printStackTrace();
250 return null;
251 }
252 }
253
254 public void putAll( Map<? extends String, ? extends Object> t )
255 {
256 if( t.keySet() == null )
257 return;
258
259 for( String key : t.keySet() )
260 {
261 put( key, t.get( key ) );
262 }
263 }
264
265 public Object remove( Object key )
266 {
267 try
268 {
269 Node node = getDomNode( key.toString() );
270 if( node != null )
271 {
272 node.getParentNode().removeChild( node );
273 }
274 }
275 catch( XmlException e )
276 {
277 e.printStackTrace();
278 }
279
280 return null;
281 }
282
283 public int size()
284 {
285 return 0;
286 }
287
288 public Collection<Object> values()
289 {
290 return null;
291 }
292 }