/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.submit.filters;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.support.AbstractHttpRequest;
import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.xml.XmlUtils;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* RequestFilter for removing empty elements/attributes
*
* @author Ole.Matzura
*/
public class RemoveEmptyContentRequestFilter extends AbstractRequestFilter {
@SuppressWarnings("unused")
private final static Logger log = Logger.getLogger(RemoveEmptyContentRequestFilter.class);
public void filterAbstractHttpRequest(SubmitContext context, AbstractHttpRequest<?> wsdlRequest) {
if (wsdlRequest != null && !wsdlRequest.isRemoveEmptyContent()) {
return;
}
String content = (String) context.getProperty(BaseHttpRequestTransport.REQUEST_CONTENT);
if (!StringUtils.hasContent(content)) {
return;
}
String soapNamespace = null;
String newContent = null;
if (wsdlRequest instanceof WsdlRequest) {
soapNamespace = ((WsdlRequest) wsdlRequest).getOperation().getInterface().getSoapVersion()
.getEnvelopeNamespace();
}
while (!content.equals(newContent)) {
if (newContent != null) {
content = newContent;
}
newContent = removeEmptyContent(content, soapNamespace, context.hasProperty("RemoveEmptyXsiNil"));
if (!context.hasProperty("RemoveEmptyRecursive")) {
break;
}
}
if (newContent != null) {
context.setProperty(BaseHttpRequestTransport.REQUEST_CONTENT, newContent);
}
}
public static String removeEmptyContent(String content, String soapNamespace, boolean removeXsiNil) {
XmlCursor cursor = null;
try {
// XmlObject xmlObject = XmlObject.Factory.parse( content );
XmlObject xmlObject = XmlUtils.createXmlObject(content);
cursor = xmlObject.newCursor();
cursor.toNextToken();
// skip root element
cursor.toNextToken();
boolean removed = false;
while (!cursor.isEnddoc()) {
boolean flag = false;
if (cursor.isContainer()
&& (soapNamespace == null || !soapNamespace.equals(cursor.getName().getNamespaceURI()))) {
Element elm = (Element) cursor.getDomNode();
NamedNodeMap attributes = elm.getAttributes();
if (attributes != null && attributes.getLength() > 0) {
for (int c = 0; c < attributes.getLength(); c++) {
Node node = attributes.item(c);
if (node.getNodeValue() == null || node.getNodeValue().trim().length() == 0) {
cursor.removeAttribute(XmlUtils.getQName(node));
removed = true;
}
}
}
if (removeXsiNil && attributes.getNamedItem("xsi:nil") != null) {
if (attributes.getLength() == 1
|| (attributes.getLength() == 2 && attributes.getNamedItem("xmlns:xsi") != null)) {
attributes.removeNamedItem("xsi:nil");
attributes.removeNamedItem("xmlns:xsi");
removed = true;
}
}
if (attributes.getLength() == 0
&& (cursor.getTextValue() == null || cursor.getTextValue().trim().length() == 0)
&& XmlUtils.getFirstChildElement(elm) == null) {
if (cursor.removeXml()) {
removed = true;
flag = true;
}
}
}
if (!flag) {
cursor.toNextToken();
}
}
if (removed) {
return xmlObject.xmlText();
}
} catch (Exception e) {
SoapUI.logError(e);
} finally {
if (cursor != null) {
cursor.dispose();
}
}
return content;
}
}