View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.impl.wsdl.submit.filters;
14  
15  import org.apache.log4j.Logger;
16  import org.apache.xmlbeans.XmlCursor;
17  import org.apache.xmlbeans.XmlObject;
18  import org.w3c.dom.Element;
19  import org.w3c.dom.NamedNodeMap;
20  import org.w3c.dom.Node;
21  
22  import com.eviware.soapui.SoapUI;
23  import com.eviware.soapui.impl.support.AbstractHttpRequest;
24  import com.eviware.soapui.impl.wsdl.WsdlRequest;
25  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
26  import com.eviware.soapui.model.iface.SubmitContext;
27  import com.eviware.soapui.support.StringUtils;
28  import com.eviware.soapui.support.xml.XmlUtils;
29  
30  /***
31   * RequestFilter for removing empty elements/attributes
32   * 
33   * @author Ole.Matzura
34   */
35  
36  public class RemoveEmptyContentRequestFilter extends AbstractRequestFilter
37  {
38  	@SuppressWarnings( "unused" )
39  	private final static Logger log = Logger.getLogger( PropertyExpansionRequestFilter.class );
40  
41  	public void filterAbstractHttpRequest( SubmitContext context, AbstractHttpRequest<?> wsdlRequest )
42  	{
43  		if( wsdlRequest != null && !wsdlRequest.isRemoveEmptyContent() )
44  			return;
45  
46  		String content = ( String )context.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );
47  		if( !StringUtils.hasContent( content ) )
48  			return;
49  
50  		String soapNamespace = null;
51  		String newContent = null;
52  
53  		if( wsdlRequest instanceof WsdlRequest )
54  			soapNamespace = ( ( WsdlRequest )wsdlRequest ).getOperation().getInterface().getSoapVersion()
55  					.getEnvelopeNamespace();
56  
57  		while( !content.equals( newContent ) )
58  		{
59  			if( newContent != null )
60  				content = newContent;
61  
62  			newContent = removeEmptyContent( content, soapNamespace, context.hasProperty( "RemoveEmptyXsiNil" ) );
63  			if( !context.hasProperty( "RemoveEmptyRecursive" ) )
64  				break;
65  		}
66  
67  		if( newContent != null )
68  			context.setProperty( BaseHttpRequestTransport.REQUEST_CONTENT, newContent );
69  	}
70  
71  	public static String removeEmptyContent( String content, String soapNamespace, boolean removeXsiNil )
72  	{
73  		XmlCursor cursor = null;
74  
75  		try
76  		{
77  			XmlObject xmlObject = XmlObject.Factory.parse( content );
78  			cursor = xmlObject.newCursor();
79  
80  			cursor.toNextToken();
81  
82  			// skip root element
83  			cursor.toNextToken();
84  			boolean removed = false;
85  
86  			while( !cursor.isEnddoc() )
87  			{
88  				boolean flag = false;
89  				if( cursor.isContainer()
90  						&& ( soapNamespace == null || !soapNamespace.equals( cursor.getName().getNamespaceURI() ) ) )
91  				{
92  					Element elm = ( Element )cursor.getDomNode();
93  					NamedNodeMap attributes = elm.getAttributes();
94  					if( attributes != null && attributes.getLength() > 0 )
95  					{
96  						for( int c = 0; c < attributes.getLength(); c++ )
97  						{
98  							Node node = attributes.item( c );
99  							if( node.getNodeValue() == null || node.getNodeValue().trim().length() == 0 )
100 							{
101 								cursor.removeAttribute( XmlUtils.getQName( node ) );
102 								removed = true;
103 							}
104 						}
105 					}
106 
107 					if( removeXsiNil && attributes.getNamedItem( "xsi:nil" ) != null )
108 					{
109 						if( attributes.getLength() == 1
110 								|| ( attributes.getLength() == 2 && attributes.getNamedItem( "xmlns:xsi" ) != null ) )
111 						{
112 							attributes.removeNamedItem( "xsi:nil" );
113 							attributes.removeNamedItem( "xmlns:xsi" );
114 							removed = true;
115 						}
116 					}
117 
118 					if( attributes.getLength() == 0 && cursor.getTextValue() == null
119 							|| cursor.getTextValue().trim().length() == 0 && XmlUtils.getFirstChildElement( elm ) == null )
120 					{
121 						if( cursor.removeXml() )
122 						{
123 							removed = true;
124 							flag = true;
125 						}
126 					}
127 				}
128 
129 				if( !flag )
130 					cursor.toNextToken();
131 			}
132 
133 			if( removed )
134 			{
135 				return xmlObject.xmlText();
136 			}
137 		}
138 		catch( Exception e )
139 		{
140 			SoapUI.logError( e );
141 		}
142 		finally
143 		{
144 			if( cursor != null )
145 				cursor.dispose();
146 		}
147 
148 		return content;
149 	}
150 }