| /* |
| * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.xml.internal.ws.model; |
| |
| import com.sun.istack.internal.NotNull; |
| import com.sun.istack.internal.localization.Localizable; |
| import com.sun.xml.internal.ws.api.BindingID; |
| import com.sun.xml.internal.ws.api.SOAPVersion; |
| import com.sun.xml.internal.ws.api.WSBinding; |
| import com.sun.xml.internal.ws.api.databinding.DatabindingConfig; |
| import com.sun.xml.internal.ws.api.databinding.MetadataReader; |
| import com.sun.xml.internal.ws.api.model.ExceptionType; |
| import com.sun.xml.internal.ws.api.model.MEP; |
| import com.sun.xml.internal.ws.api.model.Parameter; |
| import com.sun.xml.internal.ws.api.model.ParameterBinding; |
| import com.sun.xml.internal.ws.api.model.wsdl.WSDLBoundOperation; |
| import com.sun.xml.internal.ws.api.model.wsdl.WSDLInput; |
| import com.sun.xml.internal.ws.api.model.wsdl.WSDLPart; |
| import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; |
| import com.sun.xml.internal.ws.binding.WebServiceFeatureList; |
| import com.sun.xml.internal.ws.model.soap.SOAPBindingImpl; |
| import com.sun.xml.internal.ws.resources.ModelerMessages; |
| import com.sun.xml.internal.ws.resources.ServerMessages; |
| import com.sun.xml.internal.ws.spi.db.BindingContext; |
| import com.sun.xml.internal.ws.spi.db.TypeInfo; |
| import com.sun.xml.internal.ws.spi.db.WrapperComposite; |
| |
| import static com.sun.xml.internal.ws.binding.WebServiceFeatureList.getSoapVersion; |
| import static com.sun.xml.internal.ws.model.Utils.REFLECTION_NAVIGATOR; |
| |
| import javax.jws.*; |
| import javax.jws.WebParam.Mode; |
| import javax.jws.soap.SOAPBinding; |
| import javax.jws.soap.SOAPBinding.Style; |
| import javax.xml.bind.annotation.XmlElement; |
| import javax.xml.bind.annotation.XmlSeeAlso; |
| import javax.xml.namespace.QName; |
| import javax.xml.ws.*; |
| import javax.xml.ws.soap.MTOM; |
| import javax.xml.ws.soap.MTOMFeature; |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.lang.reflect.ParameterizedType; |
| import java.lang.reflect.Type; |
| import java.security.AccessController; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| import java.util.TreeMap; |
| import java.util.concurrent.Future; |
| import java.util.logging.Logger; |
| |
| import static javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED; |
| |
| /** |
| * Creates a runtime model of a SEI (portClass). |
| * |
| * @author WS Developement Team |
| */ |
| public class RuntimeModeler { |
| private final WebServiceFeatureList features; |
| private BindingID bindingId; |
| private WSBinding wsBinding; |
| private final Class portClass; |
| private AbstractSEIModelImpl model; |
| private SOAPBindingImpl defaultBinding; |
| // can be empty but never null |
| private String packageName; |
| private String targetNamespace; |
| private boolean isWrapped = true; |
| private ClassLoader classLoader; |
| private final WSDLPort binding; |
| private QName serviceName; |
| private QName portName; |
| private Set<Class> classUsesWebMethod; |
| private DatabindingConfig config; |
| private MetadataReader metadataReader; |
| /** |
| * |
| */ |
| public static final String PD_JAXWS_PACKAGE_PD = ".jaxws."; |
| /** |
| * |
| */ |
| public static final String JAXWS_PACKAGE_PD = "jaxws."; |
| public static final String RESPONSE = "Response"; |
| public static final String RETURN = "return"; |
| public static final String BEAN = "Bean"; |
| public static final String SERVICE = "Service"; |
| public static final String PORT = "Port"; |
| public static final Class HOLDER_CLASS = Holder.class; |
| public static final String REMOTE_EXCEPTION_CLASS = "java.rmi.RemoteException"; |
| public static final Class<RuntimeException> RUNTIME_EXCEPTION_CLASS = RuntimeException.class; |
| public static final Class<Exception> EXCEPTION_CLASS = Exception.class; |
| public static final String DecapitalizeExceptionBeanProperties = "com.sun.xml.internal.ws.api.model.DecapitalizeExceptionBeanProperties"; |
| public static final String SuppressDocLitWrapperGeneration = "com.sun.xml.internal.ws.api.model.SuppressDocLitWrapperGeneration"; |
| public static final String DocWrappeeNamespapceQualified = "com.sun.xml.internal.ws.api.model.DocWrappeeNamespapceQualified"; |
| |
| /*public RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, @NotNull BindingID bindingId, @NotNull WebServiceFeature... features) { |
| this(portClass, serviceName, null, bindingId, features); |
| }*/ |
| |
| /** |
| * |
| * creates an instance of RunTimeModeler given a <code>sei</code> and <code>binding</code> |
| * @param portClass The SEI class to be modeled. |
| * @param serviceName The ServiceName to use instead of one calculated from the implementation class |
| * @param wsdlPort {@link com.sun.xml.internal.ws.api.model.wsdl.WSDLPort} |
| * @param features web service features |
| */ |
| /*public RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, @NotNull WSDLPortImpl wsdlPort, @NotNull WebServiceFeature... features){ |
| this(portClass, serviceName, wsdlPort, wsdlPort.getBinding().getBindingId(), features); |
| }*/ |
| |
| /*private RuntimeModeler(@NotNull Class portClass, @NotNull QName serviceName, WSDLPortImpl binding, BindingID bindingId, @NotNull WebServiceFeature... features) { |
| this.portClass = portClass; |
| this.serviceName = serviceName; |
| this.binding = binding; |
| this.bindingId = bindingId; |
| this.features = features; |
| }*/ |
| |
| public RuntimeModeler(@NotNull DatabindingConfig config){ |
| this.portClass = (config.getEndpointClass() != null)? config.getEndpointClass() : config.getContractClass(); |
| this.serviceName = config.getMappingInfo().getServiceName(); |
| this.binding = config.getWsdlPort(); |
| this.classLoader = config.getClassLoader(); |
| this.portName = config.getMappingInfo().getPortName(); |
| this.config = config; |
| this.wsBinding = config.getWSBinding(); |
| metadataReader = config.getMetadataReader(); |
| targetNamespace = config.getMappingInfo().getTargetNamespace(); |
| if (metadataReader == null) metadataReader = new ReflectAnnotationReader(); |
| if (wsBinding != null) { |
| this.bindingId = wsBinding.getBindingId(); |
| if (config.getFeatures() != null) wsBinding.getFeatures().mergeFeatures(config.getFeatures(), false); |
| if (binding != null) wsBinding.getFeatures().mergeFeatures(binding.getFeatures(), false); |
| this.features = WebServiceFeatureList.toList(wsBinding.getFeatures()); |
| } else { |
| this.bindingId = config.getMappingInfo().getBindingID(); |
| this.features = WebServiceFeatureList.toList(config.getFeatures()); |
| if (binding != null) bindingId = binding.getBinding().getBindingId(); |
| if (bindingId == null) bindingId = getDefaultBindingID(); |
| if (!features.contains(MTOMFeature.class)) { |
| MTOM mtomAn = getAnnotation(portClass, MTOM.class); |
| if (mtomAn != null) features.add(WebServiceFeatureList.getFeature(mtomAn)); |
| } |
| if (!features.contains(com.oracle.webservices.internal.api.EnvelopeStyleFeature.class)) { |
| com.oracle.webservices.internal.api.EnvelopeStyle es = getAnnotation(portClass, com.oracle.webservices.internal.api.EnvelopeStyle.class); |
| if (es != null) features.add(WebServiceFeatureList.getFeature(es)); |
| } |
| this.wsBinding = bindingId.createBinding(features); |
| } |
| } |
| |
| private BindingID getDefaultBindingID() { |
| BindingType bt = getAnnotation(portClass, BindingType.class); |
| if (bt != null) return BindingID.parse(bt.value()); |
| SOAPVersion ver = getSoapVersion(features); |
| boolean mtomEnabled = features.isEnabled(MTOMFeature.class); |
| if (SOAPVersion.SOAP_12.equals(ver)) { |
| return (mtomEnabled) ? BindingID.SOAP12_HTTP_MTOM : BindingID.SOAP12_HTTP; |
| } else { |
| return (mtomEnabled) ? BindingID.SOAP11_HTTP_MTOM : BindingID.SOAP11_HTTP; |
| } |
| } |
| |
| /** |
| * sets the classloader to be used when loading classes by the <code>RuntimeModeler</code>. |
| * @param classLoader ClassLoader used to load classes |
| */ |
| public void setClassLoader(ClassLoader classLoader) { |
| this.classLoader = classLoader; |
| } |
| |
| /** |
| * sets the PortName to be used by the <code>RuntimeModeler</code>. |
| * @param portName The PortName to be used instead of the PortName |
| * retrieved via annotations |
| */ |
| public void setPortName(QName portName) { |
| this.portName = portName; |
| } |
| |
| private <T extends Annotation> T getAnnotation(final Class<?> clazz, final Class<T> T) { |
| return metadataReader.getAnnotation(T, clazz); |
| } |
| |
| private <T extends Annotation> T getAnnotation(final Method method, final Class<T> T) { |
| return metadataReader.getAnnotation(T, method); |
| } |
| |
| private Annotation[] getAnnotations(final Method method) { |
| return metadataReader.getAnnotations(method); |
| } |
| |
| private Annotation[] getAnnotations(final Class<?> c) { |
| return metadataReader.getAnnotations(c); |
| } |
| private Annotation[][] getParamAnnotations(final Method method) { |
| return metadataReader.getParameterAnnotations(method); |
| } |
| |
| private static final Logger logger = |
| Logger.getLogger( |
| com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server"); |
| |
| //currently has many local vars which will be eliminated after debugging issues |
| //first draft |
| /** |
| * builds the runtime model from the <code>portClass</code> using the binding ID <code>bindingId</code>. |
| * @return the runtime model for the <code>portClass</code>. |
| */ |
| public AbstractSEIModelImpl buildRuntimeModel() { |
| model = new SOAPSEIModel(features); |
| model.contractClass = config.getContractClass(); |
| model.endpointClass = config.getEndpointClass(); |
| model.classLoader = this.classLoader; |
| model.wsBinding = wsBinding; |
| model.databindingInfo.setWsdlURL(config.getWsdlURL()); |
| model.databindingInfo.properties().putAll(config.properties()); |
| if (model.contractClass == null) model.contractClass = portClass; |
| if (model.endpointClass == null && !portClass.isInterface()) model.endpointClass = portClass; |
| Class<?> seiClass = portClass; |
| metadataReader.getProperties(model.databindingInfo.properties(), portClass); |
| WebService webService = getAnnotation(portClass, WebService.class); |
| if (webService == null) { |
| throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", |
| portClass.getCanonicalName()); |
| } |
| Class<?> seiFromConfig = configEndpointInterface(); |
| if (webService.endpointInterface().length() > 0 || seiFromConfig != null) { |
| if (seiFromConfig != null) { |
| seiClass = seiFromConfig; |
| } else { |
| seiClass = getClass(webService.endpointInterface(), ModelerMessages.localizableRUNTIME_MODELER_CLASS_NOT_FOUND(webService.endpointInterface())); |
| } |
| model.contractClass = seiClass; |
| model.endpointClass = portClass; |
| WebService seiService = getAnnotation(seiClass, WebService.class); |
| if (seiService == null) { |
| throw new RuntimeModelerException("runtime.modeler.endpoint.interface.no.webservice", |
| webService.endpointInterface()); |
| } |
| |
| //check if @SOAPBinding is defined on the impl class |
| SOAPBinding sbPortClass = getAnnotation(portClass, SOAPBinding.class); |
| SOAPBinding sbSei = getAnnotation(seiClass, SOAPBinding.class); |
| if(sbPortClass != null){ |
| if(sbSei == null || sbSei.style() != sbPortClass.style()|| sbSei.use() != sbPortClass.use()){ |
| logger.warning(ServerMessages.RUNTIMEMODELER_INVALIDANNOTATION_ON_IMPL("@SOAPBinding", portClass.getName(), seiClass.getName())); |
| } |
| } |
| } |
| if (serviceName == null) |
| serviceName = getServiceName(portClass, metadataReader); |
| model.setServiceQName(serviceName); |
| |
| // String portLocalName = portClass.getSimpleName()+PORT; |
| // if (webService.portName().length() >0) { |
| // portLocalName = webService.portName(); |
| // } else if (webService.name().length() >0) { |
| // portLocalName = webService.name()+PORT; |
| // } |
| // |
| // if (portName == null) |
| // portName = new QName(serviceName.getNamespaceURI(), portLocalName); |
| // if (!portName.getNamespaceURI().equals(serviceName.getNamespaceURI())) { |
| // throw new RuntimeModelerException("runtime.modeler.portname.servicename.namespace.mismatch", |
| // serviceName, portName); |
| // } |
| |
| if (portName == null) portName = getPortName(portClass, metadataReader, serviceName.getNamespaceURI()); |
| model.setPortName(portName); |
| |
| // Check if databinding is overridden in annotation. |
| com.oracle.webservices.internal.api.databinding.DatabindingMode dbm2 = getAnnotation(portClass, com.oracle.webservices.internal.api.databinding.DatabindingMode.class); |
| if (dbm2 != null) model.databindingInfo.setDatabindingMode(dbm2.value()); |
| |
| processClass(seiClass); |
| if (model.getJavaMethods().size() == 0) |
| throw new RuntimeModelerException("runtime.modeler.no.operations", |
| portClass.getName()); |
| model.postProcess(); |
| |
| // Make the configured databinding mode available to the |
| // DatabindingConfig. |
| config.properties().put(BindingContext.class.getName(), |
| model.bindingContext); |
| |
| // TODO: this needs to be fixed properly -- |
| // when we are building RuntimeModel first before building WSDLModel, |
| // we still need to do this correctly |
| if(binding!=null) |
| model.freeze(binding); |
| return model; |
| } |
| |
| private Class configEndpointInterface() { |
| if (config.getEndpointClass() == null || |
| config.getEndpointClass().isInterface() ) return null; //client proxy Interface |
| return config.getContractClass(); |
| } |
| |
| /** |
| * utility method to load classes |
| * @param className the name of the class to load |
| * @param errorMessage |
| * Error message to use when the resolution fails. |
| * @return the class specified by <code>className</code> |
| */ |
| private Class getClass(String className, Localizable errorMessage) { |
| try { |
| if (classLoader == null) |
| return Thread.currentThread().getContextClassLoader().loadClass(className); |
| else |
| return classLoader.loadClass(className); |
| } catch (ClassNotFoundException e) { |
| throw new RuntimeModelerException(errorMessage); |
| } |
| } |
| |
| private boolean noWrapperGen() { |
| Object o = config.properties().get(SuppressDocLitWrapperGeneration); |
| return (o!= null && o instanceof Boolean) ? ((Boolean) o) : false; |
| } |
| |
| private Class getRequestWrapperClass(String className, Method method, QName reqElemName) { |
| ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader; |
| try { |
| return loader.loadClass(className); |
| } catch (ClassNotFoundException e) { |
| if (noWrapperGen()) return WrapperComposite.class; |
| logger.fine("Dynamically creating request wrapper Class " + className); |
| return WrapperBeanGenerator.createRequestWrapperBean(className, method, reqElemName, loader); |
| } |
| } |
| |
| private Class getResponseWrapperClass(String className, Method method, QName resElemName) { |
| ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader; |
| try { |
| return loader.loadClass(className); |
| } catch (ClassNotFoundException e) { |
| if (noWrapperGen()) return WrapperComposite.class; |
| logger.fine("Dynamically creating response wrapper bean Class " + className); |
| return WrapperBeanGenerator.createResponseWrapperBean(className, method, resElemName, loader); |
| } |
| } |
| |
| |
| private Class getExceptionBeanClass(String className, Class exception, String name, String namespace) { |
| boolean decapitalizeExceptionBeanProperties = true; |
| Object o = config.properties().get(DecapitalizeExceptionBeanProperties); |
| if (o!= null && o instanceof Boolean) decapitalizeExceptionBeanProperties = (Boolean) o; |
| ClassLoader loader = (classLoader == null) ? Thread.currentThread().getContextClassLoader() : classLoader; |
| try { |
| return loader.loadClass(className); |
| } catch (ClassNotFoundException e) { |
| if (noWrapperGen()) return exception; |
| logger.fine("Dynamically creating exception bean Class " + className); |
| return WrapperBeanGenerator.createExceptionBean(className, exception, targetNamespace, name, namespace, loader, decapitalizeExceptionBeanProperties); |
| } |
| } |
| |
| protected void determineWebMethodUse(Class clazz) { |
| if (clazz == null) |
| return; |
| if (!clazz.isInterface()) { |
| if (clazz == Object.class) |
| return; |
| WebMethod webMethod; |
| for (Method method : clazz.getMethods()) { |
| if (method.getDeclaringClass()!=clazz) |
| continue; |
| webMethod = getAnnotation(method, WebMethod.class); |
| if (webMethod != null && !webMethod.exclude()) { |
| classUsesWebMethod.add(clazz); |
| break; |
| } |
| } |
| } |
| determineWebMethodUse(clazz.getSuperclass()); |
| } |
| |
| void processClass(Class clazz) { |
| classUsesWebMethod = new HashSet<Class>(); |
| determineWebMethodUse(clazz); |
| WebService webService = getAnnotation(clazz, WebService.class); |
| QName portTypeName = getPortTypeName(clazz, targetNamespace, metadataReader); |
| // String portTypeLocalName = clazz.getSimpleName(); |
| // if (webService.name().length() >0) |
| // portTypeLocalName = webService.name(); |
| // |
| // targetNamespace = webService.targetNamespace(); |
| packageName = ""; |
| if (clazz.getPackage() != null) |
| packageName = clazz.getPackage().getName(); |
| // if (targetNamespace.length() == 0) { |
| // targetNamespace = getNamespace(packageName); |
| // } |
| // model.setTargetNamespace(targetNamespace); |
| // QName portTypeName = new QName(targetNamespace, portTypeLocalName); |
| targetNamespace = portTypeName.getNamespaceURI(); |
| model.setPortTypeName(portTypeName); |
| model.setTargetNamespace(targetNamespace); |
| model.defaultSchemaNamespaceSuffix = config.getMappingInfo().getDefaultSchemaNamespaceSuffix(); |
| model.setWSDLLocation(webService.wsdlLocation()); |
| |
| SOAPBinding soapBinding = getAnnotation(clazz, SOAPBinding.class); |
| if (soapBinding != null) { |
| if (soapBinding.style() == SOAPBinding.Style.RPC && soapBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) { |
| throw new RuntimeModelerException("runtime.modeler.invalid.soapbinding.parameterstyle", |
| soapBinding, clazz); |
| |
| } |
| isWrapped = soapBinding.parameterStyle()== WRAPPED; |
| } |
| defaultBinding = createBinding(soapBinding); |
| /* |
| * if clazz != portClass then there is an SEI. If there is an |
| * SEI, then all methods should be processed. However, if there is |
| * no SEI, and the implementation class uses at least one |
| * WebMethod annotation, then only methods with this annotation |
| * will be processed. |
| */ |
| /* if (clazz == portClass) { |
| WebMethod webMethod; |
| for (Method method : clazz.getMethods()) { |
| webMethod = getPrivMethodAnnotation(method, WebMethod.class); |
| if (webMethod != null && |
| !webMethod.exclude()) { |
| usesWebMethod = true; |
| break; |
| } |
| } |
| }*/ |
| |
| for (Method method : clazz.getMethods()) { |
| if (!clazz.isInterface()) { // if clazz is SEI, then all methods are web methods |
| if (method.getDeclaringClass() == Object.class) continue; |
| if (!getBooleanSystemProperty("com.sun.xml.internal.ws.legacyWebMethod")) { // legacy webMethod computation behaviour to be used |
| if (!isWebMethodBySpec(method, clazz)) |
| continue; |
| } else { |
| if (!isWebMethod(method)) |
| continue; |
| } |
| } |
| // TODO: binding can be null. We need to figure out how to post-process |
| // RuntimeModel to link to WSDLModel |
| processMethod(method); |
| } |
| //Add additional jaxb classes referenced by {@link XmlSeeAlso} |
| XmlSeeAlso xmlSeeAlso = getAnnotation(clazz, XmlSeeAlso.class); |
| if(xmlSeeAlso != null) |
| model.addAdditionalClasses(xmlSeeAlso.value()); |
| } |
| |
| /* |
| * Section 3.3 of spec |
| * Otherwise, the class implicitly defines a service endpoint interface (SEI) which |
| * comprises all of the public methods that satisfy one of the following conditions: |
| * 1. They are annotated with the javax.jws.WebMethod annotation with the exclude element set to |
| * false or missing (since false is the default for this annotation element). |
| * 2. They are not annotated with the javax.jws.WebMethod annotation but their declaring class has a |
| * javax.jws.WebService annotation. |
| * |
| * also the method should non-static or non-final |
| */ |
| private boolean isWebMethodBySpec(Method method, Class clazz) { |
| |
| int modifiers = method.getModifiers(); |
| boolean staticFinal = Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers); |
| |
| assert Modifier.isPublic(modifiers); |
| assert !clazz.isInterface(); |
| |
| WebMethod webMethod = getAnnotation(method, WebMethod.class); |
| if (webMethod != null) { |
| if (webMethod.exclude()) { |
| return false; // @WebMethod(exclude="true") |
| } |
| if (staticFinal) { |
| throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_NONSTATICFINAL(method)); |
| } |
| return true; // @WebMethod |
| } |
| |
| if (staticFinal) { |
| return false; |
| } |
| |
| Class declClass = method.getDeclaringClass(); |
| return getAnnotation(declClass, WebService.class) != null; |
| } |
| |
| private boolean isWebMethod(Method method) { |
| int modifiers = method.getModifiers(); |
| if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) |
| return false; |
| |
| Class clazz = method.getDeclaringClass(); |
| boolean declHasWebService = getAnnotation(clazz, WebService.class) != null; |
| WebMethod webMethod = getAnnotation(method, WebMethod.class); |
| if (webMethod != null && !webMethod.exclude() && declHasWebService) |
| return true; |
| return declHasWebService && !classUsesWebMethod.contains(clazz); |
| } |
| |
| /** |
| * creates a runtime model <code>SOAPBinding</code> from a <code>javax.jws.soap.SOAPBinding</code> object |
| * @param soapBinding the <code>javax.jws.soap.SOAPBinding</code> to model |
| * @return returns the runtime model SOAPBinding corresponding to <code>soapBinding</code> |
| */ |
| protected SOAPBindingImpl createBinding(SOAPBinding soapBinding) { |
| SOAPBindingImpl rtSOAPBinding = new SOAPBindingImpl(); |
| Style style = soapBinding!=null ? soapBinding.style() : Style.DOCUMENT; |
| rtSOAPBinding.setStyle(style); |
| assert bindingId != null; |
| model.bindingId = bindingId; |
| SOAPVersion soapVersion = bindingId.getSOAPVersion(); |
| rtSOAPBinding.setSOAPVersion(soapVersion); |
| return rtSOAPBinding; |
| } |
| |
| /** |
| * gets the namespace <code>String</code> for a given <code>packageName</code> |
| * @param packageName the name of the package used to find a namespace. |
| * can be empty. |
| * @return the namespace for the specified <code>packageName</code> |
| */ |
| public static String getNamespace(@NotNull String packageName) { |
| if (packageName.length() == 0) |
| return null; |
| |
| StringTokenizer tokenizer = new StringTokenizer(packageName, "."); |
| String[] tokens; |
| if (tokenizer.countTokens() == 0) { |
| tokens = new String[0]; |
| } else { |
| tokens = new String[tokenizer.countTokens()]; |
| for (int i=tokenizer.countTokens()-1; i >= 0; i--) { |
| tokens[i] = tokenizer.nextToken(); |
| } |
| } |
| StringBuilder namespace = new StringBuilder("http://"); |
| for (int i=0; i<tokens.length; i++) { |
| if (i!=0) |
| namespace.append('.'); |
| namespace.append(tokens[i]); |
| } |
| namespace.append('/'); |
| return namespace.toString(); |
| } |
| |
| /* |
| * Returns true if an exception is service specific exception as per JAX-WS rules. |
| * @param exception |
| * @return |
| */ |
| private boolean isServiceException(Class<?> exception) { |
| return EXCEPTION_CLASS.isAssignableFrom(exception) && |
| !(RUNTIME_EXCEPTION_CLASS.isAssignableFrom(exception) || isRemoteException(exception)); |
| } |
| |
| /** |
| * creates the runtime model for a method on the <code>portClass</code> |
| * @param method the method to model |
| */ |
| private void processMethod(Method method) { |
| // int mods = method.getModifiers(); |
| WebMethod webMethod = getAnnotation(method, WebMethod.class); |
| if (webMethod != null && webMethod.exclude()) return; |
| /* |
| validations are already done |
| |
| if (!Modifier.isPublic(mods) || Modifier.isStatic(mods)) { |
| if(webMethod != null) { |
| // if the user put @WebMethod on these non-qualifying method, |
| // it's an error |
| if(Modifier.isStatic(mods)) |
| throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_NONSTATIC(method)); |
| else |
| throw new RuntimeModelerException(ModelerMessages.localizableRUNTIME_MODELER_WEBMETHOD_MUST_BE_PUBLIC(method)); |
| } |
| return; |
| } |
| |
| if (webMethod != null && webMethod.exclude()) |
| return; |
| */ |
| |
| String methodName = method.getName(); |
| boolean isOneway = (getAnnotation(method, Oneway.class) != null); |
| |
| //Check that oneway methods don't thorw any checked exceptions |
| if (isOneway) { |
| for (Class<?> exception : method.getExceptionTypes()) { |
| if(isServiceException(exception)) { |
| throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.checked.exceptions", |
| portClass.getCanonicalName(), methodName, exception.getName()); |
| } |
| } |
| } |
| |
| JavaMethodImpl javaMethod; |
| //Class implementorClass = portClass; |
| if (method.getDeclaringClass()==portClass) { |
| javaMethod = new JavaMethodImpl(model,method,method,metadataReader); |
| } else { |
| try { |
| Method tmpMethod = portClass.getMethod(method.getName(), |
| method.getParameterTypes()); |
| javaMethod = new JavaMethodImpl(model,tmpMethod,method,metadataReader); |
| } catch (NoSuchMethodException e) { |
| throw new RuntimeModelerException("runtime.modeler.method.not.found", |
| method.getName(), portClass.getName()); |
| } |
| } |
| |
| |
| |
| //set MEP -oneway, async, req/resp |
| MEP mep = getMEP(method); |
| javaMethod.setMEP(mep); |
| |
| String action = null; |
| |
| |
| String operationName = method.getName(); |
| if (webMethod != null ) { |
| action = webMethod.action(); |
| operationName = webMethod.operationName().length() > 0 ? |
| webMethod.operationName() : |
| operationName; |
| } |
| |
| //override the @WebMethod.action value by the one from the WSDL |
| if(binding != null){ |
| WSDLBoundOperation bo = binding.getBinding().get(new QName(targetNamespace, operationName)); |
| if(bo != null){ |
| WSDLInput wsdlInput = bo.getOperation().getInput(); |
| String wsaAction = wsdlInput.getAction(); |
| if(wsaAction != null && !wsdlInput.isDefaultAction()) |
| action = wsaAction; |
| else |
| action = bo.getSOAPAction(); |
| } |
| } |
| |
| javaMethod.setOperationQName(new QName(targetNamespace,operationName)); |
| SOAPBinding methodBinding = getAnnotation(method, SOAPBinding.class); |
| if(methodBinding != null && methodBinding.style() == SOAPBinding.Style.RPC) { |
| logger.warning(ModelerMessages.RUNTIMEMODELER_INVALID_SOAPBINDING_ON_METHOD(methodBinding, method.getName(), method.getDeclaringClass().getName())); |
| } else if (methodBinding == null && !method.getDeclaringClass().equals(portClass)) { |
| methodBinding = getAnnotation(method.getDeclaringClass(), SOAPBinding.class); |
| if (methodBinding != null && methodBinding.style() == SOAPBinding.Style.RPC && methodBinding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) { |
| throw new RuntimeModelerException("runtime.modeler.invalid.soapbinding.parameterstyle", |
| methodBinding, method.getDeclaringClass()); |
| } |
| } |
| |
| if(methodBinding!= null && defaultBinding.getStyle() != methodBinding.style()) { |
| throw new RuntimeModelerException("runtime.modeler.soapbinding.conflict", |
| methodBinding.style(), method.getName(),defaultBinding.getStyle()); |
| } |
| |
| boolean methodIsWrapped = isWrapped; |
| Style style = defaultBinding.getStyle(); |
| if (methodBinding != null) { |
| SOAPBindingImpl mySOAPBinding = createBinding(methodBinding); |
| style = mySOAPBinding.getStyle(); |
| if (action != null) |
| mySOAPBinding.setSOAPAction(action); |
| methodIsWrapped = methodBinding.parameterStyle().equals( |
| WRAPPED); |
| javaMethod.setBinding(mySOAPBinding); |
| } else { |
| SOAPBindingImpl sb = new SOAPBindingImpl(defaultBinding); |
| if (action != null) { |
| sb.setSOAPAction(action); |
| } else { |
| String defaults = SOAPVersion.SOAP_11 == sb.getSOAPVersion() ? "" : null; |
| sb.setSOAPAction(defaults); |
| } |
| javaMethod.setBinding(sb); |
| } |
| if (!methodIsWrapped) { |
| processDocBareMethod(javaMethod, operationName, method); |
| } else if (style.equals(Style.DOCUMENT)) { |
| processDocWrappedMethod(javaMethod, methodName, operationName, |
| method); |
| } else { |
| processRpcMethod(javaMethod, methodName, operationName, method); |
| } |
| model.addJavaMethod(javaMethod); |
| } |
| |
| private MEP getMEP(Method m){ |
| if (getAnnotation(m, Oneway.class)!= null) { |
| return MEP.ONE_WAY; |
| } |
| if(Response.class.isAssignableFrom(m.getReturnType())){ |
| return MEP.ASYNC_POLL; |
| }else if(Future.class.isAssignableFrom(m.getReturnType())){ |
| return MEP.ASYNC_CALLBACK; |
| } |
| return MEP.REQUEST_RESPONSE; |
| } |
| |
| /** |
| * models a document/literal wrapped method |
| * @param javaMethod the runtime model <code>JavaMethod</code> instance being created |
| * @param methodName the runtime model <code>JavaMethod</code> instance being created |
| * @param operationName the runtime model <code>JavaMethod</code> instance being created |
| * @param method the <code>method</code> to model |
| */ |
| protected void processDocWrappedMethod(JavaMethodImpl javaMethod, String methodName, |
| String operationName, Method method) { |
| boolean methodHasHeaderParams = false; |
| boolean isOneway = getAnnotation(method, Oneway.class)!= null; |
| RequestWrapper reqWrapper = getAnnotation(method,RequestWrapper.class); |
| ResponseWrapper resWrapper = getAnnotation(method,ResponseWrapper.class); |
| String beanPackage = packageName + PD_JAXWS_PACKAGE_PD; |
| if (packageName == null || packageName.length() == 0) { |
| beanPackage = JAXWS_PACKAGE_PD; |
| } |
| String requestClassName; |
| if(reqWrapper != null && reqWrapper.className().length()>0){ |
| requestClassName = reqWrapper.className(); |
| }else{ |
| requestClassName = beanPackage + capitalize(method.getName()); |
| } |
| |
| |
| String responseClassName; |
| if(resWrapper != null && resWrapper.className().length()>0){ |
| responseClassName = resWrapper.className(); |
| }else{ |
| responseClassName = beanPackage + capitalize(method.getName()) + RESPONSE; |
| } |
| |
| String reqName = operationName; |
| String reqNamespace = targetNamespace; |
| String reqPartName = "parameters"; |
| if (reqWrapper != null) { |
| if (reqWrapper.targetNamespace().length() > 0) |
| reqNamespace = reqWrapper.targetNamespace(); |
| if (reqWrapper.localName().length() > 0) |
| reqName = reqWrapper.localName(); |
| try { |
| if (reqWrapper.partName().length() > 0) |
| reqPartName = reqWrapper.partName(); |
| } catch(LinkageError e) { |
| //2.1 API dopes n't have this method |
| //Do nothing, just default to "parameters" |
| } |
| } |
| QName reqElementName = new QName(reqNamespace, reqName); |
| javaMethod.setRequestPayloadName(reqElementName); |
| Class requestClass = getRequestWrapperClass(requestClassName, method, reqElementName); |
| |
| Class responseClass = null; |
| String resName = operationName+"Response"; |
| String resNamespace = targetNamespace; |
| QName resElementName = null; |
| String resPartName = "parameters"; |
| if (!isOneway) { |
| if (resWrapper != null) { |
| if (resWrapper.targetNamespace().length() > 0) |
| resNamespace = resWrapper.targetNamespace(); |
| if (resWrapper.localName().length() > 0) |
| resName = resWrapper.localName(); |
| try { |
| if (resWrapper.partName().length() > 0) |
| resPartName = resWrapper.partName(); |
| } catch (LinkageError e) { |
| //2.1 API does n't have this method |
| //Do nothing, just default to "parameters" |
| } |
| } |
| resElementName = new QName(resNamespace, resName); |
| responseClass = getResponseWrapperClass(responseClassName, method, resElementName); |
| } |
| |
| TypeInfo typeRef = |
| new TypeInfo(reqElementName, requestClass); |
| typeRef.setNillable(false); |
| WrapperParameter requestWrapper = new WrapperParameter(javaMethod, typeRef, |
| Mode.IN, 0); |
| requestWrapper.setPartName(reqPartName); |
| requestWrapper.setBinding(ParameterBinding.BODY); |
| javaMethod.addParameter(requestWrapper); |
| WrapperParameter responseWrapper = null; |
| if (!isOneway) { |
| typeRef = new TypeInfo(resElementName, responseClass); |
| typeRef.setNillable(false); |
| responseWrapper = new WrapperParameter(javaMethod, typeRef, Mode.OUT, -1); |
| javaMethod.addParameter(responseWrapper); |
| responseWrapper.setBinding(ParameterBinding.BODY); |
| } |
| |
| // return value |
| |
| |
| WebResult webResult = getAnnotation(method, WebResult.class); |
| XmlElement xmlElem = getAnnotation(method, XmlElement.class); |
| QName resultQName = getReturnQName(method, webResult, xmlElem); |
| Class returnType = method.getReturnType(); |
| boolean isResultHeader = false; |
| if (webResult != null) { |
| isResultHeader = webResult.header(); |
| methodHasHeaderParams = isResultHeader || methodHasHeaderParams; |
| if (isResultHeader && xmlElem != null) { |
| throw new RuntimeModelerException("@XmlElement cannot be specified on method "+method+" as the return value is bound to header"); |
| } |
| if (resultQName.getNamespaceURI().length() == 0 && webResult.header()) { |
| // headers must have a namespace |
| resultQName = new QName(targetNamespace, resultQName.getLocalPart()); |
| } |
| } |
| |
| if(javaMethod.isAsync()){ |
| returnType = getAsyncReturnType(method, returnType); |
| resultQName = new QName(RETURN); |
| } |
| resultQName = qualifyWrappeeIfNeeded(resultQName, resNamespace); |
| if (!isOneway && (returnType != null) && (!returnType.getName().equals("void"))) { |
| Annotation[] rann = getAnnotations(method); |
| if (resultQName.getLocalPart() != null) { |
| TypeInfo rTypeReference = new TypeInfo(resultQName, returnType, rann); |
| metadataReader.getProperties(rTypeReference.properties(), method); |
| rTypeReference.setGenericType(method.getGenericReturnType()); |
| ParameterImpl returnParameter = new ParameterImpl(javaMethod, rTypeReference, Mode.OUT, -1); |
| if (isResultHeader) { |
| returnParameter.setBinding(ParameterBinding.HEADER); |
| javaMethod.addParameter(returnParameter); |
| } else { |
| returnParameter.setBinding(ParameterBinding.BODY); |
| responseWrapper.addWrapperChild(returnParameter); |
| } |
| } |
| } |
| |
| //get WebParam |
| Class<?>[] parameterTypes = method.getParameterTypes(); |
| Type[] genericParameterTypes = method.getGenericParameterTypes(); |
| Annotation[][] pannotations = getParamAnnotations(method); |
| int pos = 0; |
| for (Class clazzType : parameterTypes) { |
| String partName=null; |
| String paramName = "arg"+pos; |
| //String paramNamespace = ""; |
| boolean isHeader = false; |
| |
| if(javaMethod.isAsync() && AsyncHandler.class.isAssignableFrom(clazzType)){ |
| continue; |
| } |
| |
| boolean isHolder = HOLDER_CLASS.isAssignableFrom(clazzType); |
| //set the actual type argument of Holder in the TypeReference |
| if (isHolder) { |
| if(clazzType==Holder.class){ |
| clazzType = erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]); |
| } |
| } |
| Mode paramMode = isHolder ? Mode.INOUT : Mode.IN; |
| WebParam webParam = null; |
| xmlElem = null; |
| for (Annotation annotation : pannotations[pos]) { |
| if (annotation.annotationType() == WebParam.class) |
| webParam = (WebParam)annotation; |
| else if (annotation.annotationType() == XmlElement.class) |
| xmlElem = (XmlElement)annotation; |
| } |
| |
| QName paramQName = getParameterQName(method, webParam, xmlElem, paramName); |
| if (webParam != null) { |
| isHeader = webParam.header(); |
| methodHasHeaderParams = isHeader || methodHasHeaderParams; |
| if (isHeader && xmlElem != null) { |
| throw new RuntimeModelerException("@XmlElement cannot be specified on method "+method+" parameter that is bound to header"); |
| } |
| if(webParam.partName().length() > 0) |
| partName = webParam.partName(); |
| else |
| partName = paramQName.getLocalPart(); |
| if (isHeader && paramQName.getNamespaceURI().equals("")) { // headers cannot be in empty namespace |
| paramQName = new QName(targetNamespace, paramQName.getLocalPart()); |
| } |
| paramMode = webParam.mode(); |
| if (isHolder && paramMode == Mode.IN) |
| paramMode = Mode.INOUT; |
| } |
| paramQName = qualifyWrappeeIfNeeded(paramQName, reqNamespace); |
| typeRef = |
| new TypeInfo(paramQName, clazzType, pannotations[pos]); |
| metadataReader.getProperties(typeRef.properties(), method, pos); |
| typeRef.setGenericType(genericParameterTypes[pos]); |
| ParameterImpl param = new ParameterImpl(javaMethod, typeRef, paramMode, pos++); |
| |
| if (isHeader) { |
| param.setBinding(ParameterBinding.HEADER); |
| javaMethod.addParameter(param); |
| param.setPartName(partName); |
| } else { |
| param.setBinding(ParameterBinding.BODY); |
| if (paramMode!=Mode.OUT) { |
| requestWrapper.addWrapperChild(param); |
| } |
| if (paramMode!=Mode.IN) { |
| if (isOneway) { |
| throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.out.parameters", |
| portClass.getCanonicalName(), methodName); |
| } |
| responseWrapper.addWrapperChild(param); |
| } |
| } |
| } |
| |
| //If the method has any parameter or return type that is bound to a header, use "result" as part name to avoid |
| // name collison of same input part name and output part name ("parameters") shown up as param names on the |
| // client mapping. |
| if(methodHasHeaderParams) { |
| resPartName = "result"; |
| } |
| if(responseWrapper != null) |
| responseWrapper.setPartName(resPartName); |
| processExceptions(javaMethod, method); |
| } |
| |
| private QName qualifyWrappeeIfNeeded(QName resultQName, String ns) { |
| Object o = config.properties().get(DocWrappeeNamespapceQualified); |
| boolean qualified = (o!= null && o instanceof Boolean) ? ((Boolean) o) : false; |
| if (qualified) { |
| if (resultQName.getNamespaceURI() == null || "".equals(resultQName.getNamespaceURI())) { |
| return new QName(ns, resultQName.getLocalPart()); |
| } |
| } |
| return resultQName; |
| } |
| |
| /** |
| * models a rpc/literal method |
| * @param javaMethod the runtime model <code>JavaMethod</code> instance being created |
| * @param methodName the name of the <code>method</code> being modeled. |
| * @param operationName the WSDL operation name for this <code>method</code> |
| * @param method the runtime model <code>JavaMethod</code> instance being created |
| */ |
| protected void processRpcMethod(JavaMethodImpl javaMethod, String methodName, |
| String operationName, Method method) { |
| boolean isOneway = getAnnotation(method, Oneway.class) != null; |
| |
| // use Map to build parameters in the part order when they are known. |
| // if part is unbound, we just put them at the end, and for that we |
| // use a large index (10000+) to avoid colliding with ordered ones. |
| // this assumes that there's no operation with # of parameters > 10000, |
| // but I think it's a pretty safe assumption - KK. |
| Map<Integer, ParameterImpl> resRpcParams = new TreeMap<Integer, ParameterImpl>(); |
| Map<Integer, ParameterImpl> reqRpcParams = new TreeMap<Integer, ParameterImpl>(); |
| |
| //Lets take the service namespace and overwrite it with the one we get it from wsdl |
| String reqNamespace = targetNamespace; |
| String respNamespace = targetNamespace; |
| |
| if(binding != null && Style.RPC.equals(binding.getBinding().getStyle())){ |
| QName opQName = new QName(binding.getBinding().getPortTypeName().getNamespaceURI(), operationName); |
| WSDLBoundOperation op = binding.getBinding().get(opQName); |
| if(op != null){ |
| //it cant be null, but lets not fail and try to work with service namespce |
| if(op.getRequestNamespace() != null){ |
| reqNamespace = op.getRequestNamespace(); |
| } |
| |
| //it cant be null, but lets not fail and try to work with service namespce |
| if(op.getResponseNamespace() != null){ |
| respNamespace = op.getResponseNamespace(); |
| } |
| } |
| } |
| |
| QName reqElementName = new QName(reqNamespace, operationName); |
| javaMethod.setRequestPayloadName(reqElementName); |
| QName resElementName = null; |
| if (!isOneway) { |
| resElementName = new QName(respNamespace, operationName+RESPONSE); |
| } |
| |
| Class wrapperType = WrapperComposite.class; |
| TypeInfo typeRef = new TypeInfo(reqElementName, wrapperType); |
| WrapperParameter requestWrapper = new WrapperParameter(javaMethod, typeRef, Mode.IN, 0); |
| requestWrapper.setInBinding(ParameterBinding.BODY); |
| javaMethod.addParameter(requestWrapper); |
| WrapperParameter responseWrapper = null; |
| if (!isOneway) { |
| typeRef = new TypeInfo(resElementName, wrapperType); |
| responseWrapper = new WrapperParameter(javaMethod, typeRef, Mode.OUT, -1); |
| responseWrapper.setOutBinding(ParameterBinding.BODY); |
| javaMethod.addParameter(responseWrapper); |
| } |
| |
| Class returnType = method.getReturnType(); |
| String resultName = RETURN; |
| String resultTNS = targetNamespace; |
| String resultPartName = resultName; |
| boolean isResultHeader = false; |
| WebResult webResult = getAnnotation(method, WebResult.class); |
| |
| if (webResult != null) { |
| isResultHeader = webResult.header(); |
| if (webResult.name().length() > 0) |
| resultName = webResult.name(); |
| if (webResult.partName().length() > 0) { |
| resultPartName = webResult.partName(); |
| if (!isResultHeader) |
| resultName = resultPartName; |
| } else |
| resultPartName = resultName; |
| if (webResult.targetNamespace().length() > 0) |
| resultTNS = webResult.targetNamespace(); |
| isResultHeader = webResult.header(); |
| } |
| QName resultQName; |
| if (isResultHeader) |
| resultQName = new QName(resultTNS, resultName); |
| else |
| resultQName = new QName(resultName); |
| |
| if(javaMethod.isAsync()){ |
| returnType = getAsyncReturnType(method, returnType); |
| } |
| |
| if (!isOneway && returnType!=null && returnType!=void.class) { |
| Annotation[] rann = getAnnotations(method); |
| TypeInfo rTypeReference = new TypeInfo(resultQName, returnType, rann); |
| metadataReader.getProperties(rTypeReference.properties(), method); |
| rTypeReference.setGenericType(method.getGenericReturnType()); |
| ParameterImpl returnParameter = new ParameterImpl(javaMethod, rTypeReference, Mode.OUT, -1); |
| returnParameter.setPartName(resultPartName); |
| if(isResultHeader){ |
| returnParameter.setBinding(ParameterBinding.HEADER); |
| javaMethod.addParameter(returnParameter); |
| rTypeReference.setGlobalElement(true); |
| }else{ |
| ParameterBinding rb = getBinding(operationName, resultPartName, false, Mode.OUT); |
| returnParameter.setBinding(rb); |
| if(rb.isBody()){ |
| rTypeReference.setGlobalElement(false); |
| WSDLPart p = getPart(new QName(targetNamespace,operationName), resultPartName, Mode.OUT); |
| if(p == null) |
| resRpcParams.put(resRpcParams.size()+10000, returnParameter); |
| else |
| resRpcParams.put(p.getIndex(), returnParameter); |
| }else{ |
| javaMethod.addParameter(returnParameter); |
| } |
| } |
| } |
| |
| //get WebParam |
| Class<?>[] parameterTypes = method.getParameterTypes(); |
| Type[] genericParameterTypes = method.getGenericParameterTypes(); |
| Annotation[][] pannotations = getParamAnnotations(method); |
| int pos = 0; |
| for (Class clazzType : parameterTypes) { |
| String paramName = ""; |
| String paramNamespace = ""; |
| String partName = ""; |
| boolean isHeader = false; |
| |
| if(javaMethod.isAsync() && AsyncHandler.class.isAssignableFrom(clazzType)){ |
| continue; |
| } |
| |
| boolean isHolder = HOLDER_CLASS.isAssignableFrom(clazzType); |
| //set the actual type argument of Holder in the TypeReference |
| if (isHolder) { |
| if (clazzType==Holder.class) |
| clazzType = erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]); |
| } |
| Mode paramMode = isHolder ? Mode.INOUT : Mode.IN; |
| for (Annotation annotation : pannotations[pos]) { |
| if (annotation.annotationType() == javax.jws.WebParam.class) { |
| javax.jws.WebParam webParam = (javax.jws.WebParam) annotation; |
| paramName = webParam.name(); |
| partName = webParam.partName(); |
| isHeader = webParam.header(); |
| WebParam.Mode mode = webParam.mode(); |
| paramNamespace = webParam.targetNamespace(); |
| if (isHolder && mode == Mode.IN) |
| mode = Mode.INOUT; |
| paramMode = mode; |
| break; |
| } |
| } |
| |
| if (paramName.length() == 0) { |
| paramName = "arg"+pos; |
| } |
| if (partName.length() == 0) { |
| partName = paramName; |
| } else if (!isHeader) { |
| paramName = partName; |
| } |
| if (partName.length() == 0) { |
| partName = paramName; |
| } |
| |
| QName paramQName; |
| if (!isHeader) { |
| //its rpclit body param, set namespace to "" |
| paramQName = new QName("", paramName); |
| } else { |
| if (paramNamespace.length() == 0) |
| paramNamespace = targetNamespace; |
| paramQName = new QName(paramNamespace, paramName); |
| } |
| typeRef = |
| new TypeInfo(paramQName, clazzType, pannotations[pos]); |
| metadataReader.getProperties(typeRef.properties(), method, pos); |
| typeRef.setGenericType(genericParameterTypes[pos]); |
| ParameterImpl param = new ParameterImpl(javaMethod, typeRef, paramMode, pos++); |
| param.setPartName(partName); |
| |
| if(paramMode == Mode.INOUT){ |
| ParameterBinding pb = getBinding(operationName, partName, isHeader, Mode.IN); |
| param.setInBinding(pb); |
| pb = getBinding(operationName, partName, isHeader, Mode.OUT); |
| param.setOutBinding(pb); |
| }else{ |
| if (isHeader) { |
| typeRef.setGlobalElement(true); |
| param.setBinding(ParameterBinding.HEADER); |
| } else { |
| ParameterBinding pb = getBinding(operationName, partName, false, paramMode); |
| param.setBinding(pb); |
| } |
| } |
| if(param.getInBinding().isBody()){ |
| typeRef.setGlobalElement(false); |
| if(!param.isOUT()){ |
| WSDLPart p = getPart(new QName(targetNamespace,operationName), partName, Mode.IN); |
| if(p == null) |
| reqRpcParams.put(reqRpcParams.size()+10000, param); |
| else |
| reqRpcParams.put(param.getIndex(), param); |
| } |
| |
| if(!param.isIN()){ |
| if (isOneway) { |
| throw new RuntimeModelerException("runtime.modeler.oneway.operation.no.out.parameters", |
| portClass.getCanonicalName(), methodName); |
| } |
| WSDLPart p = getPart(new QName(targetNamespace,operationName), partName, Mode.OUT); |
| if(p == null) |
| resRpcParams.put(resRpcParams.size()+10000, param); |
| else |
| resRpcParams.put(p.getIndex(), param); |
| } |
| }else{ |
| javaMethod.addParameter(param); |
| } |
| } |
| for (ParameterImpl p : reqRpcParams.values()) |
| requestWrapper.addWrapperChild(p); |
| for (ParameterImpl p : resRpcParams.values()) |
| responseWrapper.addWrapperChild(p); |
| processExceptions(javaMethod, method); |
| } |
| |
| /** |
| * models the exceptions thrown by <code>method</code> and adds them to the <code>javaMethod</code> |
| * runtime model object |
| * @param javaMethod the runtime model object to add the exception model objects to |
| * @param method the <code>method</code> from which to find the exceptions to model |
| */ |
| protected void processExceptions(JavaMethodImpl javaMethod, Method method) { |
| Action actionAnn = getAnnotation(method, Action.class); |
| FaultAction[] faultActions = {}; |
| if(actionAnn != null) |
| faultActions = actionAnn.fault(); |
| for (Class<?> exception : method.getExceptionTypes()) { |
| |
| //Exclude RuntimeException, RemoteException and Error etc |
| if (!EXCEPTION_CLASS.isAssignableFrom(exception)) |
| continue; |
| if (RUNTIME_EXCEPTION_CLASS.isAssignableFrom(exception) || isRemoteException(exception)) |
| continue; |
| if (getAnnotation(exception, javax.xml.bind.annotation.XmlTransient.class) != null) |
| continue; |
| Class exceptionBean; |
| Annotation[] anns; |
| WebFault webFault = getAnnotation(exception, WebFault.class); |
| Method faultInfoMethod = getWSDLExceptionFaultInfo(exception); |
| ExceptionType exceptionType = ExceptionType.WSDLException; |
| String namespace = targetNamespace; |
| String name = exception.getSimpleName(); |
| String beanPackage = packageName + PD_JAXWS_PACKAGE_PD; |
| if (packageName.length() == 0) |
| beanPackage = JAXWS_PACKAGE_PD; |
| String className = beanPackage+ name + BEAN; |
| String messageName = exception.getSimpleName(); |
| if (webFault != null) { |
| if (webFault.faultBean().length()>0) |
| className = webFault.faultBean(); |
| if (webFault.name().length()>0) |
| name = webFault.name(); |
| if (webFault.targetNamespace().length()>0) |
| namespace = webFault.targetNamespace(); |
| if (webFault.messageName().length()>0) |
| messageName = webFault.messageName(); |
| } |
| if (faultInfoMethod == null) { |
| exceptionBean = getExceptionBeanClass(className, exception, name, namespace); |
| exceptionType = ExceptionType.UserDefined; |
| anns = getAnnotations(exceptionBean); |
| } else { |
| exceptionBean = faultInfoMethod.getReturnType(); |
| anns = getAnnotations(faultInfoMethod); |
| } |
| QName faultName = new QName(namespace, name); |
| TypeInfo typeRef = new TypeInfo(faultName, exceptionBean, anns); |
| CheckedExceptionImpl checkedException = |
| new CheckedExceptionImpl(javaMethod, exception, typeRef, exceptionType); |
| checkedException.setMessageName(messageName); |
| checkedException.setFaultInfoGetter(faultInfoMethod); |
| for(FaultAction fa: faultActions) { |
| if(fa.className().equals(exception) && !fa.value().equals("")) { |
| checkedException.setFaultAction(fa.value()); |
| break; |
| } |
| } |
| javaMethod.addException(checkedException); |
| } |
| } |
| |
| /** |
| * returns the method that corresponds to "getFaultInfo". Returns null if this is not an |
| * exception generated from a WSDL |
| * @param exception the class to search for the "getFaultInfo" method |
| * @return the method named "getFaultInfo" if this is an exception generated from WSDL or an |
| * exception that contains the <code>WebFault</code> annotation. Otherwise it returns null |
| */ |
| protected Method getWSDLExceptionFaultInfo(Class exception) { |
| // if (!exception.isAnnotationPresent(WebFault.class)) |
| if (getAnnotation(exception, WebFault.class) == null) |
| return null; |
| try { |
| return exception.getMethod("getFaultInfo"); |
| } catch (NoSuchMethodException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * models a document/literal bare method |
| * @param javaMethod the runtime model <code>JavaMethod</code> instance being created |
| * @param operationName the runtime model <code>JavaMethod</code> instance being created |
| * @param method the runtime model <code>JavaMethod</code> instance being created |
| */ |
| protected void processDocBareMethod(JavaMethodImpl javaMethod, |
| String operationName, Method method) { |
| |
| String resultName = operationName+RESPONSE; |
| String resultTNS = targetNamespace; |
| String resultPartName = null; |
| boolean isResultHeader = false; |
| WebResult webResult = getAnnotation(method, WebResult.class); |
| if (webResult != null) { |
| if (webResult.name().length() > 0) |
| resultName = webResult.name(); |
| if (webResult.targetNamespace().length() > 0) |
| resultTNS = webResult.targetNamespace(); |
| resultPartName = webResult.partName(); |
| isResultHeader = webResult.header(); |
| } |
| |
| Class returnType = method.getReturnType(); |
| Type gReturnType = method.getGenericReturnType(); |
| if(javaMethod.isAsync()){ |
| returnType = getAsyncReturnType(method, returnType); |
| } |
| |
| if ((returnType != null) && (!returnType.getName().equals("void"))) { |
| Annotation[] rann = getAnnotations(method); |
| if (resultName != null) { |
| QName responseQName = new QName(resultTNS, resultName); |
| TypeInfo rTypeReference = new TypeInfo(responseQName, returnType, rann); |
| rTypeReference.setGenericType(gReturnType); |
| metadataReader.getProperties(rTypeReference.properties(), method); |
| ParameterImpl returnParameter = new ParameterImpl(javaMethod, rTypeReference, Mode.OUT, -1); |
| |
| if(resultPartName == null || (resultPartName.length() == 0)){ |
| resultPartName = resultName; |
| } |
| returnParameter.setPartName(resultPartName); |
| if(isResultHeader){ |
| returnParameter.setBinding(ParameterBinding.HEADER); |
| }else{ |
| ParameterBinding rb = getBinding(operationName, resultPartName, false, Mode.OUT); |
| returnParameter.setBinding(rb); |
| } |
| javaMethod.addParameter(returnParameter); |
| } |
| } |
| |
| //get WebParam |
| Class<?>[] parameterTypes = method.getParameterTypes(); |
| Type[] genericParameterTypes = method.getGenericParameterTypes(); |
| Annotation[][] pannotations = getParamAnnotations(method); |
| int pos = 0; |
| for (Class clazzType : parameterTypes) { |
| String paramName = operationName; //method.getName(); |
| String partName = null; |
| String requestNamespace = targetNamespace; |
| boolean isHeader = false; |
| |
| //async |
| if(javaMethod.isAsync() && AsyncHandler.class.isAssignableFrom(clazzType)){ |
| continue; |
| } |
| |
| boolean isHolder = HOLDER_CLASS.isAssignableFrom(clazzType); |
| //set the actual type argument of Holder in the TypeReference |
| if (isHolder) { |
| if (clazzType==Holder.class) |
| clazzType = erasure(((ParameterizedType)genericParameterTypes[pos]).getActualTypeArguments()[0]); |
| } |
| |
| Mode paramMode = isHolder ? Mode.INOUT : Mode.IN; |
| for (Annotation annotation : pannotations[pos]) { |
| if (annotation.annotationType() == javax.jws.WebParam.class) { |
| javax.jws.WebParam webParam = (javax.jws.WebParam) annotation; |
| paramMode = webParam.mode(); |
| if (isHolder && paramMode == Mode.IN) |
| paramMode = Mode.INOUT; |
| isHeader = webParam.header(); |
| if(isHeader) |
| paramName = "arg"+pos; |
| if(paramMode == Mode.OUT && !isHeader) |
| paramName = operationName+RESPONSE; |
| if (webParam.name().length() > 0) |
| paramName = webParam.name(); |
| partName = webParam.partName(); |
| if (!webParam.targetNamespace().equals("")) { |
| requestNamespace = webParam.targetNamespace(); |
| } |
| break; |
| } |
| } |
| |
| QName requestQName = new QName(requestNamespace, paramName); |
| if (!isHeader && paramMode != Mode.OUT) javaMethod.setRequestPayloadName(requestQName); |
| //doclit/wrapped |
| TypeInfo typeRef = //operationName with upper 1 char |
| new TypeInfo(requestQName, clazzType, |
| pannotations[pos]); |
| metadataReader.getProperties(typeRef.properties(), method, pos); |
| typeRef.setGenericType(genericParameterTypes[pos]); |
| ParameterImpl param = new ParameterImpl(javaMethod, typeRef, paramMode, pos++); |
| if(partName == null || (partName.length() == 0)){ |
| partName = paramName; |
| } |
| param.setPartName(partName); |
| if(paramMode == Mode.INOUT){ |
| ParameterBinding pb = getBinding(operationName, partName, isHeader, Mode.IN); |
| param.setInBinding(pb); |
| pb = getBinding(operationName, partName, isHeader, Mode.OUT); |
| param.setOutBinding(pb); |
| }else{ |
| if (isHeader){ |
| param.setBinding(ParameterBinding.HEADER); |
| }else{ |
| ParameterBinding pb = getBinding(operationName, partName, false, paramMode); |
| param.setBinding(pb); |
| } |
| } |
| javaMethod.addParameter(param); |
| } |
| validateDocBare(javaMethod); |
| processExceptions(javaMethod, method); |
| } |
| |
| // Does a conservative check if there is only one BODY part for input |
| // and output message. We are not considering INOUT parameters at this |
| // time since binding information is not applied. Also, there isn't |
| // anyway to represent some cases in SEI. For example, a INOUT parameter |
| // could be bound to body for input message, header for OUTPUT message |
| // in wsdl:binding |
| private void validateDocBare(JavaMethodImpl javaMethod) { |
| int numInBodyBindings = 0; |
| for(Parameter param : javaMethod.getRequestParameters()){ |
| if(param.getBinding().equals(ParameterBinding.BODY) && param.isIN()){ |
| numInBodyBindings++; |
| } |
| if(numInBodyBindings > 1){ |
| throw new RuntimeModelerException(ModelerMessages.localizableNOT_A_VALID_BARE_METHOD(portClass.getName(), javaMethod.getMethod().getName())); |
| } |
| } |
| |
| int numOutBodyBindings = 0; |
| for(Parameter param : javaMethod.getResponseParameters()){ |
| if(param.getBinding().equals(ParameterBinding.BODY) && param.isOUT()){ |
| numOutBodyBindings++; |
| } |
| if(numOutBodyBindings > 1){ |
| throw new RuntimeModelerException(ModelerMessages.localizableNOT_A_VALID_BARE_METHOD(portClass.getName(), javaMethod.getMethod().getName())); |
| } |
| } |
| } |
| |
| private Class getAsyncReturnType(Method method, Class returnType) { |
| if(Response.class.isAssignableFrom(returnType)){ |
| Type ret = method.getGenericReturnType(); |
| return erasure(((ParameterizedType)ret).getActualTypeArguments()[0]); |
| }else{ |
| Type[] types = method.getGenericParameterTypes(); |
| Class[] params = method.getParameterTypes(); |
| int i = 0; |
| for(Class cls : params){ |
| if(AsyncHandler.class.isAssignableFrom(cls)){ |
| return erasure(((ParameterizedType)types[i]).getActualTypeArguments()[0]); |
| } |
| i++; |
| } |
| } |
| return returnType; |
| } |
| |
| /** |
| * utility to capitalize the first letter in a string |
| * @param name the string to capitalize |
| * @return the capitalized string |
| */ |
| public static String capitalize(String name) { |
| if (name == null || name.length() == 0) { |
| return name; |
| } |
| char chars[] = name.toCharArray(); |
| chars[0] = Character.toUpperCase(chars[0]); |
| return new String(chars); |
| } |
| |
| /* |
| * Return service QName |
| */ |
| /** |
| * gets the <code>wsdl:serviceName</code> for a given implementation class |
| * @param implClass the implementation class |
| * @return the <code>wsdl:serviceName</code> for the <code>implClass</code> |
| */ |
| public static QName getServiceName(Class<?> implClass) { |
| return getServiceName(implClass, null); |
| } |
| |
| public static QName getServiceName(Class<?> implClass, boolean isStandard) { |
| return getServiceName(implClass, null, isStandard); |
| } |
| |
| public static QName getServiceName(Class<?> implClass, MetadataReader reader) { |
| return getServiceName(implClass, reader, true); |
| } |
| |
| public static QName getServiceName(Class<?> implClass, MetadataReader reader, boolean isStandard) { |
| if (implClass.isInterface()) { |
| throw new RuntimeModelerException("runtime.modeler.cannot.get.serviceName.from.interface", |
| implClass.getCanonicalName()); |
| } |
| |
| String name = implClass.getSimpleName()+SERVICE; |
| String packageName = ""; |
| if (implClass.getPackage() != null) |
| packageName = implClass.getPackage().getName(); |
| |
| WebService webService = getAnnotation(WebService.class, implClass, reader); |
| if (isStandard && webService == null) { |
| throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", |
| implClass.getCanonicalName()); |
| } |
| if (webService != null && webService.serviceName().length() > 0) { |
| name = webService.serviceName(); |
| } |
| String targetNamespace = getNamespace(packageName); |
| if (webService != null && webService.targetNamespace().length() > 0) { |
| targetNamespace = webService.targetNamespace(); |
| } else if (targetNamespace == null) { |
| throw new RuntimeModelerException("runtime.modeler.no.package", |
| implClass.getName()); |
| } |
| return new QName(targetNamespace, name); |
| } |
| |
| /** |
| * gets the <code>wsdl:portName</code> for a given implementation class |
| * @param implClass the implementation class |
| * @param targetNamespace Namespace URI for service name |
| * @return the <code>wsdl:portName</code> for the <code>implClass</code> |
| */ |
| public static QName getPortName(Class<?> implClass, String targetNamespace) { |
| return getPortName(implClass, null, targetNamespace); |
| } |
| |
| public static QName getPortName(Class<?> implClass, String targetNamespace, boolean isStandard) { |
| return getPortName(implClass, null, targetNamespace, isStandard); |
| } |
| |
| public static QName getPortName(Class<?> implClass, MetadataReader reader, String targetNamespace) { |
| return getPortName(implClass, reader, targetNamespace, true); |
| } |
| |
| public static QName getPortName(Class<?> implClass, MetadataReader reader, String targetNamespace, boolean isStandard) { |
| WebService webService = getAnnotation(WebService.class, implClass, reader); |
| if (isStandard && webService == null) { |
| throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", |
| implClass.getCanonicalName()); |
| } |
| String name; |
| if (webService != null && webService.portName().length() > 0) { |
| name = webService.portName(); |
| } else if (webService != null && webService.name().length() > 0) { |
| name = webService.name()+PORT; |
| } else { |
| name = implClass.getSimpleName()+PORT; |
| } |
| |
| if (targetNamespace == null) { |
| if (webService != null && webService.targetNamespace().length() > 0) { |
| targetNamespace = webService.targetNamespace(); |
| } else { |
| String packageName = null; |
| if (implClass.getPackage() != null) { |
| packageName = implClass.getPackage().getName(); |
| } |
| if (packageName != null) { |
| targetNamespace = getNamespace(packageName); |
| } |
| if (targetNamespace == null) { |
| throw new RuntimeModelerException("runtime.modeler.no.package", |
| implClass.getName()); |
| } |
| } |
| |
| } |
| |
| return new QName(targetNamespace, name); |
| } |
| |
| static <A extends Annotation> A getAnnotation(Class<A> t, Class<?> cls, MetadataReader reader) { |
| return (reader == null)? cls.getAnnotation(t) : reader.getAnnotation(t, cls); |
| } |
| |
| /** |
| * Gives portType QName from implementatorClass or SEI |
| * @param implOrSeiClass cant be null |
| * @return <code>wsdl:portType@name</code>, null if it could not find the annotated class. |
| */ |
| public static QName getPortTypeName(Class<?> implOrSeiClass){ |
| return getPortTypeName(implOrSeiClass, null, null); |
| } |
| |
| public static QName getPortTypeName(Class<?> implOrSeiClass, MetadataReader metadataReader){ |
| return getPortTypeName(implOrSeiClass, null, metadataReader); |
| } |
| |
| public static QName getPortTypeName(Class<?> implOrSeiClass, String tns, MetadataReader reader){ |
| assert(implOrSeiClass != null); |
| WebService webService = getAnnotation(WebService.class, implOrSeiClass, reader); |
| Class<?> clazz = implOrSeiClass; |
| if (webService == null) |
| throw new RuntimeModelerException("runtime.modeler.no.webservice.annotation", |
| implOrSeiClass.getCanonicalName()); |
| |
| if (!implOrSeiClass.isInterface()) { |
| String epi = webService.endpointInterface(); |
| if (epi.length() > 0) { |
| try { |
| clazz = Thread.currentThread().getContextClassLoader().loadClass(epi); |
| } catch (ClassNotFoundException e) { |
| throw new RuntimeModelerException("runtime.modeler.class.not.found", epi); |
| } |
| WebService ws = getAnnotation(WebService.class, clazz, reader); |
| if (ws == null) { |
| throw new RuntimeModelerException("runtime.modeler.endpoint.interface.no.webservice", |
| webService.endpointInterface()); |
| } |
| } |
| } |
| |
| webService = getAnnotation(WebService.class, clazz, reader); |
| String name = webService.name(); |
| if(name.length() == 0){ |
| name = clazz.getSimpleName(); |
| } |
| if (tns == null || "".equals(tns.trim())) tns = webService.targetNamespace(); |
| if (tns.length() == 0) |
| tns = getNamespace(clazz.getPackage().getName()); |
| if (tns == null) { |
| throw new RuntimeModelerException("runtime.modeler.no.package", clazz.getName()); |
| } |
| return new QName(tns, name); |
| } |
| |
| private ParameterBinding getBinding(String operation, String part, boolean isHeader, Mode mode){ |
| if(binding == null){ |
| if(isHeader) |
| return ParameterBinding.HEADER; |
| else |
| return ParameterBinding.BODY; |
| } |
| QName opName = new QName(binding.getBinding().getPortType().getName().getNamespaceURI(), operation); |
| return binding.getBinding().getBinding(opName, part, mode); |
| } |
| |
| private WSDLPart getPart(QName opName, String partName, Mode mode){ |
| if(binding != null){ |
| WSDLBoundOperation bo = binding.getBinding().get(opName); |
| if(bo != null) |
| return bo.getPart(partName, mode); |
| } |
| return null; |
| } |
| |
| /* |
| * Returns true if an exception is a java.rmi.RemoteException or its subtype. |
| * |
| * @param exception |
| * @return true if an exception is a java.rmi.RemoteException or its subtype, |
| * false otherwise |
| */ |
| private boolean isRemoteException(Class<?> exception) { |
| Class<?> c = exception; |
| while (c != null && !REMOTE_EXCEPTION_CLASS.equals(c.getName())) { |
| c = c.getSuperclass(); |
| } |
| return c != null; |
| } |
| |
| private static Boolean getBooleanSystemProperty(final String prop) { |
| return AccessController.doPrivileged( |
| new java.security.PrivilegedAction<Boolean>() { |
| public Boolean run() { |
| String value = System.getProperty(prop); |
| return value != null ? Boolean.valueOf(value) : Boolean.FALSE; |
| } |
| } |
| ); |
| } |
| |
| private static QName getReturnQName(Method method, WebResult webResult, XmlElement xmlElem) { |
| String webResultName = null; |
| if (webResult != null && webResult.name().length() > 0) { |
| webResultName = webResult.name(); |
| } |
| String xmlElemName = null; |
| if (xmlElem != null && !xmlElem.name().equals("##default")) { |
| xmlElemName = xmlElem.name(); |
| } |
| if (xmlElemName != null && webResultName != null && !xmlElemName.equals(webResultName)) { |
| throw new RuntimeModelerException("@XmlElement(name)="+xmlElemName+" and @WebResult(name)="+webResultName+" are different for method " +method); |
| } |
| String localPart = RETURN; |
| if (webResultName != null) { |
| localPart = webResultName; |
| } else if (xmlElemName != null) { |
| localPart = xmlElemName; |
| } |
| |
| String webResultNS = null; |
| if (webResult != null && webResult.targetNamespace().length() > 0) { |
| webResultNS = webResult.targetNamespace(); |
| } |
| String xmlElemNS = null; |
| if (xmlElem != null && !xmlElem.namespace().equals("##default")) { |
| xmlElemNS = xmlElem.namespace(); |
| } |
| if (xmlElemNS != null && webResultNS != null && !xmlElemNS.equals(webResultNS)) { |
| throw new RuntimeModelerException("@XmlElement(namespace)="+xmlElemNS+" and @WebResult(targetNamespace)="+webResultNS+" are different for method " +method); |
| } |
| String ns = ""; |
| if (webResultNS != null) { |
| ns = webResultNS; |
| } else if (xmlElemNS != null) { |
| ns = xmlElemNS; |
| } |
| |
| return new QName(ns, localPart); |
| } |
| |
| private static QName getParameterQName(Method method, WebParam webParam, XmlElement xmlElem, String paramDefault) { |
| String webParamName = null; |
| if (webParam != null && webParam.name().length() > 0) { |
| webParamName = webParam.name(); |
| } |
| String xmlElemName = null; |
| if (xmlElem != null && !xmlElem.name().equals("##default")) { |
| xmlElemName = xmlElem.name(); |
| } |
| if (xmlElemName != null && webParamName != null && !xmlElemName.equals(webParamName)) { |
| throw new RuntimeModelerException("@XmlElement(name)="+xmlElemName+" and @WebParam(name)="+webParamName+" are different for method " +method); |
| } |
| String localPart = paramDefault; |
| if (webParamName != null) { |
| localPart = webParamName; |
| } else if (xmlElemName != null) { |
| localPart = xmlElemName; |
| } |
| |
| String webParamNS = null; |
| if (webParam != null && webParam.targetNamespace().length() > 0) { |
| webParamNS = webParam.targetNamespace(); |
| } |
| String xmlElemNS = null; |
| if (xmlElem != null && !xmlElem.namespace().equals("##default")) { |
| xmlElemNS = xmlElem.namespace(); |
| } |
| if (xmlElemNS != null && webParamNS != null && !xmlElemNS.equals(webParamNS)) { |
| throw new RuntimeModelerException("@XmlElement(namespace)="+xmlElemNS+" and @WebParam(targetNamespace)="+webParamNS+" are different for method " +method); |
| } |
| String ns = ""; |
| if (webParamNS != null) { |
| ns = webParamNS; |
| } else if (xmlElemNS != null) { |
| ns = xmlElemNS; |
| } |
| |
| return new QName(ns, localPart); |
| } |
| |
| static public Class erasure(Type type) { |
| return (Class)REFLECTION_NAVIGATOR.erasure(type); |
| } |
| } |