alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (RuntimeModeler.java)

This example Java source code file (RuntimeModeler.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

annotation, boolean, class, log, metadatareader, method, parameterbinding, parameterimpl, qname, reflection, runtimemodelerexception, soapbindingimpl, string, threading, threads, typeinfo, util, wrapperparameter, xml, xmlelement

The RuntimeModeler.java Java example source code

/*
 * Copyright (c) 1997, 2013, 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 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.rmi.RemoteException;
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 Class<RemoteException> REMOTE_EXCEPTION_CLASS = RemoteException.class;
    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 and binding
     * @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.
     * @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.
     * @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) {
        return metadataReader.getAnnotation(T, clazz);
    }

    private <T extends Annotation> T getAnnotation(final Method method, final Class 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 using the binding ID bindingId.
     * @return the runtime model for the <code>portClass.
     */
    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
     */
    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) {
            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 from a javax.jws.soap.SOAPBinding object
     * @param soapBinding the <code>javax.jws.soap.SOAPBinding to model
     * @return returns the runtime model SOAPBinding corresponding to <code>soapBinding
     */
    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 for a given packageName
     * @param packageName the name of the package used to find a namespace.
     *      can be empty.
     * @return the namespace for the specified <code>packageName
     */
    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) || REMOTE_EXCEPTION_CLASS.isAssignableFrom(exception));
    }

    /**
     * creates the runtime model for a method on the <code>portClass
     * @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 instance being created
     * @param methodName the runtime model <code>JavaMethod instance being created
     * @param operationName the runtime model <code>JavaMethod instance being created
     * @param method the <code>method 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 = (Class) Utils.REFLECTION_NAVIGATOR.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 instance being created
     * @param methodName the name of the <code>method being modeled.
     * @param operationName the WSDL operation name for this <code>method
     * @param method the runtime model <code>JavaMethod 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();
        Map<Integer, ParameterImpl> reqRpcParams = new TreeMap();

        //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 = (Class) Utils.REFLECTION_NAVIGATOR.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(p.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 and adds them to the javaMethod
     * runtime model object
     * @param javaMethod the runtime model object to add the exception model objects to
     * @param method the <code>method 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) || REMOTE_EXCEPTION_CLASS.isAssignableFrom(exception))
                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);
            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 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 instance being created
     * @param operationName the runtime model <code>JavaMethod instance being created
     * @param method the runtime model <code>JavaMethod 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 = (Class) Utils.REFLECTION_NAVIGATOR.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 (Class) Utils.REFLECTION_NAVIGATOR.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 (Class) Utils.REFLECTION_NAVIGATOR.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 for a given implementation class
     * @param implClass the implementation class
     * @return the <code>wsdl:serviceName for the implClass
     */
    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 for a given implementation class
     * @param implClass the implementation class
     * @param targetNamespace Namespace URI for service name
     * @return the <code>wsdl:portName for the implClass
     */
    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 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, 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;
    }

    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);
    }


}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.