View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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 }