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
119 							&& ( cursor.getTextValue() == null || cursor.getTextValue().trim().length() == 0 )
120 							&& XmlUtils.getFirstChildElement( elm ) == null )
121 					{
122 						if( cursor.removeXml() )
123 						{
124 							removed = true;
125 							flag = true;
126 						}
127 					}
128 				}
129 
130 				if( !flag )
131 					cursor.toNextToken();
132 			}
133 
134 			if( removed )
135 			{
136 				return xmlObject.xmlText();
137 			}
138 		}
139 		catch( Exception e )
140 		{
141 			SoapUI.logError( e );
142 		}
143 		finally
144 		{
145 			if( cursor != null )
146 				cursor.dispose();
147 		}
148 
149 		return content;
150 	}
151 }