View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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.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  		Node domNode = getDomNode( xpath );
74  		return domNode == null ? null : XmlUtils.getNodeValue( domNode );
75  	}
76  	
77  	public StringToStringMap getNamespaces()
78  	{
79  		if( declaredNamespaces == null )
80  			declaredNamespaces = new StringToStringMap();
81  		
82  		return declaredNamespaces;
83  	}
84  	
85  	public void declareNamespace( String prefix, String uri )
86  	{
87  		if( declaredNamespaces == null )
88  			declaredNamespaces = new StringToStringMap();
89  		
90  		declaredNamespaces.put( prefix, uri );
91  	}
92  	
93  	public String [] getNodeValues(String xpath ) throws XmlException
94  	{
95  		xpath = initXPathNamespaces( xpath );
96  		
97  		XmlObject[] selectPath = xmlObject.selectPath( xpath );
98  		
99  		String [] result = new String[selectPath.length];
100 		for( int c = 0; c < selectPath.length; c++ )
101 		{
102 			result[c] = XmlUtils.getNodeValue( selectPath[c].getDomNode() );
103 		}
104 		
105 		return result; 
106 	}
107 
108 	private String initXPathNamespaces( String xpath )
109 	{
110 		if( declaredNamespaces != null && !declaredNamespaces.isEmpty() )
111 		{
112 			for( String prefix : declaredNamespaces.keySet() )
113 			{
114 				xpath = "declare namespace " + prefix + "='" + declaredNamespaces.get( prefix ) + "';\n" + xpath;
115 			}
116 		} 
117 		else if( !xpath.trim().startsWith( "declare namespace" ))
118 		{
119 			xpath = XmlUtils.declareXPathNamespaces( xmlObject ) + xpath;
120 		}
121 		return xpath;
122 	}
123 	
124 	public void setNodeValue( String xpath, Object value ) throws XmlException
125 	{
126 		xpath = initXPathNamespaces( xpath );
127 
128 		XmlCursor cursor = xmlObject.newCursor();
129 		try
130 		{
131 			cursor.selectPath( xpath );
132 			
133 			if( cursor.toNextSelection() )
134 			{
135 				XmlUtils.setNodeValue( cursor.getDomNode(), value == null ? null : value.toString() );
136 			}
137 		}
138 		finally
139 		{
140 			cursor.dispose();
141 		}
142 	}
143 	
144 	public XmlObject getXmlObject()
145 	{
146 		return xmlObject;
147 	}
148 
149 	public Node getDomNode( String xpath ) throws XmlException
150 	{
151 		xpath = initXPathNamespaces( xpath );
152 		
153 		XmlCursor cursor = xmlObject.newCursor();
154 		try
155 		{
156 			cursor.selectPath( xpath );
157 			
158 			if( cursor.toNextSelection() )
159 			{
160 				return cursor.getDomNode();
161 			}
162 			else return null;
163 		}
164 		finally
165 		{
166 			cursor.dispose();
167 		}
168 	}
169 	
170 	public Node [] getDomNodes(String xpath ) throws XmlException
171 	{
172 		xpath = initXPathNamespaces( xpath );
173 		
174 		XmlObject[] selectPath = xmlObject.selectPath( xpath );
175 		
176 		Node [] result = new Node[selectPath.length];
177 		for( int c = 0; c < selectPath.length; c++ )
178 		{
179 			result[c] = selectPath[c].getDomNode();
180 		}
181 		
182 		return result; 
183 	}
184 	
185 	public void removeDomNodes( String xpath ) throws XmlException
186 	{
187 		Node [] nodes = getDomNodes( xpath );
188 		for( Node node : nodes )
189 		{
190 			node.getParentNode().removeChild( node );
191 		}
192 	}
193 	
194 	public String getXml()
195 	{
196 		return xmlObject.xmlText();
197 	}
198 	
199 	public String getPrettyXml()
200 	{
201 		return XmlUtils.prettyPrintXml( xmlObject );
202 	}
203 
204 	public void clear()
205 	{
206 	}
207 
208 	public boolean containsKey( Object key )
209 	{
210 		try
211 		{
212 			return getDomNode( key.toString() ) != null;
213 		}
214 		catch( XmlException e )
215 		{
216 			e.printStackTrace();
217 			return false;
218 		}
219 	}
220 
221 	public boolean containsValue( Object value )
222 	{
223 		try
224 		{
225 			return getNodeValue( value.toString() ) != null;
226 		}
227 		catch( XmlException e )
228 		{
229 			e.printStackTrace();
230 			return false;
231 		}
232 	}
233 
234 	public Set<java.util.Map.Entry<String, Object>> entrySet()
235 	{
236 		return null;
237 	}
238 
239 	public Object get( Object key )
240 	{
241 		try
242 		{
243 			String str = key.toString();
244 			if( str.equals( "prettyXml" ))
245 				return getPrettyXml();
246 			else if( str.equals( "xmlObject" ))
247 				return getXmlObject();
248 			else if( str.equals( "namespaces" ))
249 				return getNamespaces();
250 			else if( str.equals( "xml" ))
251 				return getXml();
252 			
253 			String[] nodeValues = getNodeValues( str );
254 			return nodeValues != null && nodeValues.length == 1 ? nodeValues[0] : nodeValues;
255 		}
256 		catch( XmlException e )
257 		{
258 			e.printStackTrace();
259 			return null;
260 		}
261 	}
262 
263 	public boolean isEmpty()
264 	{
265 		return false;
266 	}
267 
268 	public Set<String> keySet()
269 	{
270 		return null;
271 	}
272 
273 	public String put( String key, Object value )
274 	{
275 		try
276 		{
277 			String result = getNodeValue( key );
278 			setNodeValue( key, value == null ? null : value.toString() );
279 			return result;
280 		}
281 		catch( XmlException e )
282 		{
283 			e.printStackTrace();
284 			return null;
285 		}
286 	}
287 
288 	public void putAll( Map<? extends String, ? extends Object> t )
289 	{
290 		if( t.keySet() == null )
291 			return;
292 		
293 		for( String key : t.keySet() )
294 		{
295 			put( key, t.get( key ));
296 		}
297 	}
298 
299 	public Object remove( Object key )
300 	{
301 		try
302 		{
303 			Node node = getDomNode( key.toString() );
304 			if( node != null )
305 			{
306 				node.getParentNode().removeChild( node );
307 			}
308 		}
309 		catch( XmlException e )
310 		{
311 			e.printStackTrace();
312 		}
313 		
314 		return null;
315 	}
316 
317 	public int size()
318 	{
319 		return 0;
320 	}
321 
322 	public Collection<Object> values()
323 	{
324 		return null;
325 	}
326 }