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 String getXml()
176 {
177 return xmlObject.xmlText();
178 }
179
180 public String getPrettyXml()
181 {
182 return XmlUtils.prettyPrintXml( xmlObject );
183 }
184
185 public void clear()
186 {
187 }
188
189 public boolean containsKey( Object key )
190 {
191 try
192 {
193 return getDomNode( key.toString() ) != null;
194 }
195 catch( XmlException e )
196 {
197 e.printStackTrace();
198 return false;
199 }
200 }
201
202 public boolean containsValue( Object value )
203 {
204 try
205 {
206 return getNodeValue( value.toString() ) != null;
207 }
208 catch( XmlException e )
209 {
210 e.printStackTrace();
211 return false;
212 }
213 }
214
215 public Set<java.util.Map.Entry<String, Object>> entrySet()
216 {
217 return null;
218 }
219
220 public Object get( Object key )
221 {
222 try
223 {
224 String str = key.toString();
225 if( str.equals( "prettyXml" ))
226 return getPrettyXml();
227 else if( str.equals( "xmlObject" ))
228 return getXmlObject();
229 else if( str.equals( "namespaces" ))
230 return getNamespaces();
231 else if( str.equals( "xml" ))
232 return getXml();
233
234 String[] nodeValues = getNodeValues( str );
235 return nodeValues != null && nodeValues.length == 1 ? nodeValues[0] : nodeValues;
236 }
237 catch( XmlException e )
238 {
239 e.printStackTrace();
240 return null;
241 }
242 }
243
244 public boolean isEmpty()
245 {
246 return false;
247 }
248
249 public Set<String> keySet()
250 {
251 return null;
252 }
253
254 public String put( String key, Object value )
255 {
256 try
257 {
258 String result = getNodeValue( key );
259 setNodeValue( key, value == null ? null : value.toString() );
260 return result;
261 }
262 catch( XmlException e )
263 {
264 e.printStackTrace();
265 return null;
266 }
267 }
268
269 public void putAll( Map<? extends String, ? extends Object> t )
270 {
271 if( t.keySet() == null )
272 return;
273
274 for( String key : t.keySet() )
275 {
276 put( key, t.get( key ));
277 }
278 }
279
280 public Object remove( Object key )
281 {
282 try
283 {
284 Node node = getDomNode( key.toString() );
285 if( node != null )
286 {
287 node.getParentNode().removeChild( node );
288 }
289 }
290 catch( XmlException e )
291 {
292 e.printStackTrace();
293 }
294
295 return null;
296 }
297
298 public int size()
299 {
300 return 0;
301 }
302
303 public Collection<Object> values()
304 {
305 return null;
306 }
307 }