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