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