1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.support;
14
15 import java.util.Collection;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.apache.xmlbeans.XmlCursor;
20 import org.apache.xmlbeans.XmlException;
21 import org.apache.xmlbeans.XmlObject;
22 import org.w3c.dom.Node;
23
24 import com.eviware.soapui.model.testsuite.TestRunContext;
25 import com.eviware.soapui.support.types.StringToStringMap;
26 import com.eviware.soapui.support.xml.XmlUtils;
27
28 public class XmlHolder implements Map<String,Object>
29 {
30 private XmlObject xmlObject;
31 private StringToStringMap declaredNamespaces;
32 private TestRunContext context;
33 private String propertyRef;
34
35 public XmlHolder( String xml ) throws XmlException
36 {
37 xmlObject = XmlObject.Factory.parse( xml );
38 }
39
40 public XmlHolder( TestRunContext context, String propertyRef ) throws XmlException
41 {
42 this( context.getProperty( propertyRef ).toString() );
43
44 this.context = context;
45 this.propertyRef = propertyRef;
46 }
47
48 public void updateProperty()
49 {
50 updateProperty( false );
51 }
52
53 public void updateProperty( boolean prettyPrint )
54 {
55 if( context != null && propertyRef != null )
56 {
57 context.setProperty( propertyRef, prettyPrint ? getPrettyXml() : getXml() );
58 }
59 }
60
61 public String getNodeValue( String xpath ) throws XmlException
62 {
63 Node domNode = getDomNode( xpath );
64 return domNode == null ? null : XmlUtils.getNodeValue( domNode );
65 }
66
67 public Map getNamespaces()
68 {
69 if( declaredNamespaces == null )
70 declaredNamespaces = new StringToStringMap();
71
72 return declaredNamespaces;
73 }
74
75 public void declareNamespace( String prefix, String uri )
76 {
77 if( declaredNamespaces == null )
78 declaredNamespaces = new StringToStringMap();
79
80 declaredNamespaces.put( prefix, uri );
81 }
82
83 public String [] getNodeValues(String xpath ) throws XmlException
84 {
85 xpath = initXPathNamespaces( xpath );
86
87 XmlObject[] selectPath = xmlObject.selectPath( xpath );
88
89 String [] result = new String[selectPath.length];
90 for( int c = 0; c < selectPath.length; c++ )
91 {
92 result[c] = XmlUtils.getNodeValue( selectPath[c].getDomNode() );
93 }
94
95 return result;
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, String 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 );
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
143 XmlCursor cursor = xmlObject.newCursor();
144 try
145 {
146 cursor.selectPath( xpath );
147
148 if( cursor.toNextSelection() )
149 {
150 return cursor.getDomNode();
151 }
152 else return null;
153 }
154 finally
155 {
156 cursor.dispose();
157 }
158 }
159
160 public Node [] getDomNodes(String xpath ) throws XmlException
161 {
162 xpath = initXPathNamespaces( xpath );
163
164 XmlObject[] selectPath = xmlObject.selectPath( xpath );
165
166 Node [] result = new Node[selectPath.length];
167 for( int c = 0; c < selectPath.length; c++ )
168 {
169 result[c] = selectPath[c].getDomNode();
170 }
171
172 return result;
173 }
174
175 public void removeDomNodes( String xpath ) throws XmlException
176 {
177 Node [] nodes = getDomNodes( xpath );
178 for( Node node : nodes )
179 {
180 node.getParentNode().removeChild( node );
181 }
182 }
183
184 public String getXml()
185 {
186 return xmlObject.xmlText();
187 }
188
189 public String getPrettyXml()
190 {
191 return XmlUtils.prettyPrintXml( xmlObject );
192 }
193
194 public void clear()
195 {
196 }
197
198 public boolean containsKey( Object key )
199 {
200 try
201 {
202 return getDomNode( key.toString() ) != null;
203 }
204 catch( XmlException e )
205 {
206 e.printStackTrace();
207 return false;
208 }
209 }
210
211 public boolean containsValue( Object value )
212 {
213 try
214 {
215 return getNodeValue( value.toString() ) != null;
216 }
217 catch( XmlException e )
218 {
219 e.printStackTrace();
220 return false;
221 }
222 }
223
224 public Set<java.util.Map.Entry<String, Object>> entrySet()
225 {
226 return null;
227 }
228
229 public Object get( Object key )
230 {
231 try
232 {
233 String str = key.toString();
234 if( str.equals( "prettyXml" ))
235 return getPrettyXml();
236 else if( str.equals( "xmlObject" ))
237 return getXmlObject();
238 else if( str.equals( "namespaces" ))
239 return getNamespaces();
240 else if( str.equals( "xml" ))
241 return getXml();
242
243 String[] nodeValues = getNodeValues( str );
244 return nodeValues != null && nodeValues.length == 1 ? nodeValues[0] : nodeValues;
245 }
246 catch( XmlException e )
247 {
248 e.printStackTrace();
249 return null;
250 }
251 }
252
253 public boolean isEmpty()
254 {
255 return false;
256 }
257
258 public Set<String> keySet()
259 {
260 return null;
261 }
262
263 public String put( String key, Object value )
264 {
265 try
266 {
267 String result = getNodeValue( key );
268 setNodeValue( key, value == null ? null : value.toString() );
269 return result;
270 }
271 catch( XmlException e )
272 {
273 e.printStackTrace();
274 return null;
275 }
276 }
277
278 public void putAll( Map<? extends String, ? extends Object> t )
279 {
280 if( t.keySet() == null )
281 return;
282
283 for( String key : t.keySet() )
284 {
285 put( key, t.get( key ));
286 }
287 }
288
289 public Object remove( Object key )
290 {
291 try
292 {
293 Node node = getDomNode( key.toString() );
294 if( node != null )
295 {
296 node.getParentNode().removeChild( node );
297 }
298 }
299 catch( XmlException e )
300 {
301 e.printStackTrace();
302 }
303
304 return null;
305 }
306
307 public int size()
308 {
309 return 0;
310 }
311
312 public Collection<Object> values()
313 {
314 return null;
315 }
316 }