/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.cxf.binding.soap; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.wsdl.Binding; import javax.wsdl.BindingFault; import javax.wsdl.BindingInput; import javax.wsdl.BindingOperation; import javax.wsdl.BindingOutput; import javax.wsdl.Definition; import javax.wsdl.Port; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.ExtensionRegistry; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPBody; import javax.wsdl.extensions.soap.SOAPFault; import javax.wsdl.extensions.soap.SOAPHeader; import javax.wsdl.extensions.soap.SOAPOperation; import javax.wsdl.extensions.soap12.SOAP12Address; import javax.wsdl.extensions.soap12.SOAP12Binding; import javax.wsdl.extensions.soap12.SOAP12Body; import javax.wsdl.extensions.soap12.SOAP12Fault; import javax.wsdl.extensions.soap12.SOAP12Header; import javax.wsdl.extensions.soap12.SOAP12Operation; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.wsdl.extensions.SoapAddress; import org.apache.cxf.binding.soap.wsdl.extensions.SoapBinding; import org.apache.cxf.binding.soap.wsdl.extensions.SoapBody; import org.apache.cxf.binding.soap.wsdl.extensions.SoapFault; import org.apache.cxf.binding.soap.wsdl.extensions.SoapHeader; import org.apache.cxf.binding.soap.wsdl.extensions.SoapOperation; import org.apache.cxf.common.util.ExtensionInvocationHandler; import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.wsdl.WSDLConstants; public final class SOAPBindingUtil { private static Map<String, String> bindingMap = new HashMap<>(); static { bindingMap.put("RPC", "SOAPBinding.Style.RPC"); bindingMap.put("DOCUMENT", "SOAPBinding.Style.DOCUMENT"); bindingMap.put("LITERAL", "SOAPBinding.Use.LITERAL"); bindingMap.put("ENCODED", "SOAPBinding.Use.ENCODED"); bindingMap.put("BARE", "SOAPBinding.ParameterStyle.BARE"); bindingMap.put("WRAPPED", "SOAPBinding.ParameterStyle.WRAPPED"); } private SOAPBindingUtil() { } public static String getBindingAnnotation(String key) { return bindingMap.get(key.toUpperCase()); } public static <T> T getProxy(Class<T> cls, Object obj) { InvocationHandler ih = new ExtensionInvocationHandler(obj); /* * If we put proxies into the loader of the proxied class, they'll just pile up. */ Object proxy = null; try { proxy = Proxy.newProxyInstance(getContextClassLoader(), new Class[] {cls}, ih); } catch (Throwable ex) { // Using cls classloader as a fallback to make it work within OSGi ClassLoader contextLoader = getContextClassLoader(); final ClassLoader clsClassLoader = getClassLoader(cls); if (contextLoader != clsClassLoader) { proxy = Proxy.newProxyInstance(clsClassLoader, new Class[] {cls}, ih); } else { if (ex instanceof RuntimeException) { throw (RuntimeException)ex; } throw new RuntimeException(ex); } } return cls.cast(proxy); } private static ClassLoader getContextClassLoader() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); } }); } return Thread.currentThread().getContextClassLoader(); } private static ClassLoader getClassLoader(final Class<?> clazz) { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { public ClassLoader run() { return clazz.getClassLoader(); } }); } return clazz.getClassLoader(); } public static boolean isSOAPBinding(Binding binding) { for (Object obj : binding.getExtensibilityElements()) { if (isSOAPBinding(obj)) { return true; } } return false; } public static String getBindingStyle(Binding binding) { for (Object obj : binding.getExtensibilityElements()) { if (isSOAPBinding(obj)) { return getSoapBinding(obj).getStyle(); } } return ""; } public static SoapOperation getSoapOperation(List<ExtensibilityElement> exts) { if (exts != null) { for (ExtensibilityElement ext : exts) { if (isSOAPOperation(ext)) { return getSoapOperation(ext); } } } return null; } public static SoapOperation getSoapOperation(Object obj) { if (isSOAPOperation(obj)) { return getProxy(SoapOperation.class, obj); } return null; } public static String getSOAPOperationStyle(BindingOperation bop) { String style = ""; if (bop != null) { for (Object obj : bop.getExtensibilityElements()) { if (isSOAPOperation(obj)) { style = getSoapOperation(obj).getStyle(); break; } } } return style; } public static SoapBody getBindingInputSOAPBody(BindingOperation bop) { BindingInput bindingInput = bop.getBindingInput(); if (bindingInput != null) { for (Object obj : bindingInput.getExtensibilityElements()) { if (isSOAPBody(obj)) { return getSoapBody(obj); } } } return null; } public static SoapBody getBindingOutputSOAPBody(BindingOperation bop) { BindingOutput bindingOutput = bop.getBindingOutput(); if (bindingOutput != null) { for (Object obj : bindingOutput.getExtensibilityElements()) { if (isSOAPBody(obj)) { return getSoapBody(obj); } } } return null; } public static SoapBody getSoapBody(List<ExtensibilityElement> exts) { if (exts != null) { for (ExtensibilityElement ext : exts) { if (isSOAPBody(ext)) { return getSoapBody(ext); } } } return null; } public static SoapBody getSoapBody(Object obj) { if (isSOAPBody(obj)) { return getProxy(SoapBody.class, obj); } return null; } public static boolean isSOAPBody(Object obj) { return obj instanceof SOAPBody || obj instanceof SOAP12Body; } public static boolean isSOAPHeader(Object obj) { return obj instanceof SOAPHeader || obj instanceof SOAP12Header; } public static List<SoapHeader> getSoapHeaders(List<ExtensibilityElement> exts) { List<SoapHeader> headers = new ArrayList<>(); if (exts != null) { for (ExtensibilityElement ext : exts) { if (isSOAPHeader(ext)) { headers.add(getSoapHeader(ext)); } } } return headers; } public static SoapHeader getSoapHeader(Object obj) { if (isSOAPHeader(obj)) { return getProxy(SoapHeader.class, obj); } return null; } public static SoapAddress getSoapAddress(Object obj) { if (isSOAPAddress(obj)) { return getProxy(SoapAddress.class, obj); } return null; } public static boolean isSOAPAddress(Object obj) { return obj instanceof SOAPAddress || obj instanceof SOAP12Address; } public static SoapHeader getBindingInputSOAPHeader(BindingOperation bop) { BindingInput bindingInput = bop.getBindingInput(); if (bindingInput != null) { for (Object obj : bindingInput.getExtensibilityElements()) { if (isSOAPHeader(obj)) { return getProxy(SoapHeader.class, obj); } } } return null; } public static List<SoapHeader> getBindingInputSOAPHeaders(BindingOperation bop) { List<SoapHeader> headers = new ArrayList<>(); BindingInput bindingInput = bop.getBindingInput(); if (bindingInput != null) { for (Object obj : bindingInput.getExtensibilityElements()) { if (isSOAPHeader(obj)) { headers.add(getProxy(SoapHeader.class, obj)); } } } return headers; } public static SoapHeader getBindingOutputSOAPHeader(BindingOperation bop) { BindingOutput bindingOutput = bop.getBindingOutput(); if (bindingOutput != null) { for (Object obj : bindingOutput.getExtensibilityElements()) { if (isSOAPHeader(obj)) { return getProxy(SoapHeader.class, obj); } } } return null; } public static List<SoapHeader> getBindingOutputSOAPHeaders(BindingOperation bop) { List<SoapHeader> headers = new ArrayList<>(); BindingOutput bindingOutput = bop.getBindingOutput(); if (bindingOutput != null) { for (Object obj : bindingOutput.getExtensibilityElements()) { if (isSOAPHeader(obj)) { headers.add(getProxy(SoapHeader.class, obj)); } } } return headers; } public static SoapBinding getSoapBinding(List<ExtensibilityElement> exts) { for (ExtensibilityElement ext : exts) { if (isSOAPBinding(ext)) { return getSoapBinding(ext); } } return null; } public static SoapBinding getSoapBinding(Object obj) { if (isSOAPBinding(obj)) { return getProxy(SoapBinding.class, obj); } return null; } public static boolean isSOAPBinding(Object obj) { return obj instanceof SOAPBinding || obj instanceof SOAP12Binding; } public static List<SoapFault> getBindingOperationSoapFaults(BindingOperation bop) { List<SoapFault> faults = new ArrayList<>(); for (Object obj : bop.getBindingFaults().values()) { if (!(obj instanceof BindingFault)) { continue; } BindingFault faultElement = (BindingFault) obj; for (Object flt : faultElement.getExtensibilityElements()) { SoapFault fault = getSoapFault(flt); if (fault != null) { faults.add(fault); } } } return faults; } public static SoapFault getSoapFault(Object obj) { if (isSOAPFault(obj)) { return getProxy(SoapFault.class, obj); } return null; } public static boolean isMixedStyle(Binding binding) { String bindingStyle = ""; String previousOpStyle = ""; String style = ""; for (Object obj : binding.getExtensibilityElements()) { if (isSOAPBinding(obj)) { SoapBinding soapBinding = getSoapBinding(obj); bindingStyle = soapBinding.getStyle(); if (bindingStyle == null) { bindingStyle = ""; } } } for (Object bobj : binding.getBindingOperations()) { BindingOperation bop = (BindingOperation)bobj; for (Object obj : bop.getExtensibilityElements()) { if (isSOAPOperation(obj)) { SoapOperation soapOperation = getSoapOperation(obj); style = soapOperation.getStyle(); if (style == null) { style = ""; } if ("".equals(bindingStyle) && "".equals(previousOpStyle) || "".equals(bindingStyle) && previousOpStyle.equalsIgnoreCase(style)) { previousOpStyle = style; } else if (!"".equals(bindingStyle) && "".equals(previousOpStyle) && bindingStyle.equalsIgnoreCase(style) || bindingStyle.equalsIgnoreCase(previousOpStyle) && bindingStyle.equalsIgnoreCase(style)) { previousOpStyle = style; } else if (!"".equals(bindingStyle) && "".equals(style) && "".equals(previousOpStyle)) { continue; } else { return true; } } } } return false; } public static String getCanonicalBindingStyle(Binding binding) { String bindingStyle = getBindingStyle(binding); if (!StringUtils.isEmpty(bindingStyle)) { return bindingStyle; } for (Object bobj : binding.getBindingOperations()) { BindingOperation bindingOp = (BindingOperation)bobj; String bopStyle = getSOAPOperationStyle(bindingOp); if (!StringUtils.isEmpty(bopStyle)) { return bopStyle; } } return ""; } public static boolean isSOAPOperation(Object obj) { return obj instanceof SOAPOperation || obj instanceof SOAP12Operation; } public static boolean isSOAPFault(Object obj) { return obj instanceof SOAPFault || obj instanceof SOAP12Fault; } public static SoapAddress createSoapAddress(ExtensionRegistry extReg, boolean isSOAP12) throws WSDLException { ExtensibilityElement extElement = null; if (isSOAP12) { extElement = extReg.createExtension(Port.class, WSDLConstants.QNAME_SOAP12_BINDING_ADDRESS); } else { extElement = extReg.createExtension(Port.class, WSDLConstants.QNAME_SOAP_BINDING_ADDRESS); } return getSoapAddress(extElement); } public static SoapBody createSoapBody(ExtensionRegistry extReg, Class<?> clz, boolean isSOAP12) throws WSDLException { ExtensibilityElement extElement = null; if (isSOAP12) { extElement = extReg.createExtension(clz, new QName(WSDLConstants.NS_SOAP12, "body")); } else { extElement = extReg.createExtension(clz, new QName(WSDLConstants.NS_SOAP11, "body")); } return getSoapBody(extElement); } public static SoapBinding createSoapBinding(ExtensionRegistry extReg, boolean isSOAP12) throws WSDLException { ExtensibilityElement extElement = null; if (isSOAP12) { extElement = extReg.createExtension(Binding.class, new QName(WSDLConstants.NS_SOAP12, "binding")); ((SOAP12Binding)extElement).setTransportURI(WSDLConstants.NS_SOAP_HTTP_TRANSPORT); } else { extElement = extReg.createExtension(Binding.class, new QName(WSDLConstants.NS_SOAP11, "binding")); ((SOAPBinding)extElement).setTransportURI(WSDLConstants.NS_SOAP_HTTP_TRANSPORT); } return getSoapBinding(extElement); } public static SoapOperation createSoapOperation(ExtensionRegistry extReg, boolean isSOAP12) throws WSDLException { ExtensibilityElement extElement = null; if (isSOAP12) { extElement = extReg.createExtension(BindingOperation.class, new QName(WSDLConstants.NS_SOAP12, "operation")); } else { extElement = extReg.createExtension(BindingOperation.class, new QName(WSDLConstants.NS_SOAP11, "operation")); } return getSoapOperation(extElement); } public static SoapFault createSoapFault(ExtensionRegistry extReg, boolean isSOAP12) throws WSDLException { ExtensibilityElement extElement = null; if (isSOAP12) { extElement = extReg.createExtension(BindingFault.class, new QName(WSDLConstants.NS_SOAP12, "fault")); } else { extElement = extReg.createExtension(BindingFault.class, new QName(WSDLConstants.NS_SOAP11, "fault")); } return getSoapFault(extElement); } public static SoapHeader createSoapHeader(ExtensionRegistry extReg, Class<?> clz, boolean isSOAP12) throws WSDLException { ExtensibilityElement extElement = null; if (isSOAP12) { extElement = extReg.createExtension(clz, new QName(WSDLConstants.NS_SOAP12, "header")); } else { extElement = extReg.createExtension(clz, new QName(WSDLConstants.NS_SOAP11, "header")); } return getSoapHeader(extElement); } public static void addSOAPNamespace(Definition definition, boolean isSOAP12) { Map<?, ?> namespaces = definition.getNamespaces(); if (isSOAP12 && !namespaces.values().contains(WSDLConstants.NS_SOAP12)) { definition.addNamespace("soap12", WSDLConstants.NS_SOAP12); } else if (!namespaces.values().contains(WSDLConstants.NS_SOAP11)) { definition.addNamespace("soap", WSDLConstants.NS_SOAP11); } } public static javax.jws.soap.SOAPBinding.Style getSoapStyle(String soapStyle) { if ("".equals(soapStyle)) { return null; } else if ("RPC".equalsIgnoreCase(soapStyle)) { return javax.jws.soap.SOAPBinding.Style.RPC; } else { return javax.jws.soap.SOAPBinding.Style.DOCUMENT; } } public static javax.jws.soap.SOAPBinding.Use getSoapUse(String soapUse) { if ("".equals(soapUse)) { return null; } else if ("ENCODED".equalsIgnoreCase(soapUse)) { return javax.jws.soap.SOAPBinding.Use.ENCODED; } else { return javax.jws.soap.SOAPBinding.Use.LITERAL; } } }