All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.webservices.WebServiceReferenceManagerImpl Maven / Gradle / Ivy

There is a newer version: 7.2024.1.Alpha1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2009-2015 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.webservices;

import com.sun.enterprise.deployment.*;
import com.sun.xml.ws.api.server.*;
import com.sun.xml.ws.transport.http.servlet.ServletAdapter;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.deployment.versioning.VersioningUtils;
import org.jvnet.hk2.annotations.Service;

import com.sun.enterprise.container.common.spi.WebServiceReferenceManager;
import com.sun.xml.ws.api.FeatureConstructor;
import com.sun.xml.ws.resources.ModelerMessages;

import javax.inject.Inject;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.InitialContext;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceFactory;
import javax.xml.ws.soap.MTOMFeature;
import javax.xml.ws.soap.AddressingFeature;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.RespectBindingFeature;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.spi.WebServiceFeatureAnnotation;
import java.io.*;
import java.lang.reflect.*;
import java.lang.annotation.Annotation;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.security.PrivilegedActionException;
import java.net.URL;


/**
 * This class acts as a service to resolve the
 * javax.xml.ws.WebServiceRef references
 * and also javax.xml.ws.WebServiceContext
 * Whenever a lookup is done from GlassfishNamingManagerImpl
 * these methods are invoked to resolve the references
 *
 * @author Bhakti Mehta
 */

@Service
public class WebServiceReferenceManagerImpl implements WebServiceReferenceManager {

    @Inject
    private ServerEnvironment serverEnv;

    protected Logger logger = LogUtils.getLogger();

    public Object getWSContextObject() {
        return new WebServiceContextImpl();
    }

    public Object resolveWSReference(ServiceReferenceDescriptor desc, Context context)
            throws NamingException {


        //Taken from NamingManagerImpl.getClientServiceObject
        Class serviceInterfaceClass = null;
        Object returnObj = null;
        WsUtil wsUtil = new WsUtil();

        //Implementation for new lookup element in WebserviceRef
        InitialContext iContext = new InitialContext();
        if( desc.hasLookupName()) {
            return iContext.lookup(desc.getLookupName());

        }

        try {

            WSContainerResolver.set(desc);

            ClassLoader cl = Thread.currentThread().getContextClassLoader();

            serviceInterfaceClass = cl.loadClass(desc.getServiceInterface());

            resolvePortComponentLinks(desc);

            javax.xml.rpc.Service serviceDelegate = null;
            javax.xml.ws.Service jaxwsDelegate = null;
            Object injValue = null;

            if( desc.hasGeneratedServiceInterface() || desc.hasWsdlFile() ) {

                String serviceImplName  = desc.getServiceImplClassName();
                if(serviceImplName != null) {
                    Class serviceImplClass  = cl.loadClass(serviceImplName);
                    serviceDelegate = (javax.xml.rpc.Service) serviceImplClass.newInstance();
                } else {

                    // The target is probably a post JAXRPC-1.1- based service;
                    // If Service Interface class is set, check if it is indeed a subclass of Service
                    // initiateInstance should not be called if the user has given javax.xml.ws.Service itself
                    // as the interface through DD
                    if(javax.xml.ws.Service.class.isAssignableFrom(serviceInterfaceClass) &&
                            !javax.xml.ws.Service.class.equals(serviceInterfaceClass) ) {
                        // OK - the interface class is indeed the generated service class; get an instance
                        injValue = initiateInstance(serviceInterfaceClass, desc);
                    } else {
                        // First try failed; Try to get the Service class type from injected field name
                        // and from there try to get an instance of the service class

                        // I assume the at all inejction target are expecting the SAME service
                        // interface, therefore I take the first one.
                        if (desc.isInjectable()) {

                            InjectionTarget target = desc.getInjectionTargets().iterator().next();
                            Class serviceType = null;
                            if (target.isFieldInjectable()) {
                                java.lang.reflect.Field f = target.getField();
                                if(f == null) {
                                    String fName = target.getFieldName();
                                    Class targetClass = cl.loadClass(target.getClassName());
                                    try {
                                        f = targetClass.getDeclaredField(fName);
                                    } catch(java.lang.NoSuchFieldException nsfe) {}// ignoring exception
                                }
                                if(f != null) {
                                    serviceType = f.getType();
                                }
                            }
                            if (target.isMethodInjectable()) {
                                Method m = target.getMethod();
                                if(m == null) {
                                    String mName = target.getMethodName();
                                    Class targetClass = cl.loadClass(target.getClassName());
                                    try {
                                        m = targetClass.getDeclaredMethod(mName);
                                    } catch(java.lang.NoSuchMethodException nsfe) {}// ignoring exception
                                }
                                if (m != null && m.getParameterTypes().length==1) {
                                    serviceType = m.getParameterTypes()[0];
                                }
                            }
                            if (serviceType!=null){
                                Class loadedSvcClass = cl.loadClass(serviceType.getCanonicalName());
                                injValue = initiateInstance(loadedSvcClass, desc);
                            }
                        }
                    }
                    // Unable to get hold of generated service class -> try the Service.create avenue to get a Service
                    if(injValue == null) {
                        // Here create the service with WSDL (overridden wsdl if wsdl-override is present)
                        // so that JAXWS runtime uses this wsdl @ runtime
                        javax.xml.ws.Service svc =
                                javax.xml.ws.Service.create((new WsUtil()).privilegedGetServiceRefWsdl(desc),
                                        desc.getServiceName());
                        jaxwsDelegate = new JAXWSServiceDelegate(desc, svc, cl);
                    }
                }

                if( desc.hasHandlers() ) {
                    // We need the service's ports to configure the
                    // handler chain (since service-ref handler chain can
                    // optionally specify handler-port association)
                    // so create a configured service and call getPorts

                    javax.xml.rpc.Service configuredService =
                            wsUtil.createConfiguredService(desc);
                    Iterator ports = configuredService.getPorts();
                    wsUtil.configureHandlerChain
                            (desc, serviceDelegate, ports, cl);
                }

                // check if this is a post 1.1 web service
                if(javax.xml.ws.Service.class.isAssignableFrom(serviceInterfaceClass)) {
                    // This is a JAXWS based webservice client;
                    // process handlers and mtom setting
                    // moved test for handlers into wsUtil, in case
                    // we have to add system handler

                    javax.xml.ws.Service service =
                            (injValue != null ?
                                    (javax.xml.ws.Service) injValue : jaxwsDelegate);

                    if (service != null) {
                        // Now configure client side handlers
                        wsUtil.configureJAXWSClientHandlers(service, desc);
                    }
                    // the requested resource is not the service but one of its port.
                    if (injValue!=null && desc.getInjectionTargetType()!=null) {
                        Class requestedPortType = service.getClass().getClassLoader().loadClass(desc.getInjectionTargetType());
                        ArrayList wsFeatures = getWebServiceFeatures(desc);
                        if (wsFeatures.size() >0) {
                             injValue = service.getPort(requestedPortType,wsFeatures.toArray(new WebServiceFeature[wsFeatures.size()]));
                        }   else {
                            injValue = service.getPort(requestedPortType);
                        }
                    }

                }

            } else {
                // Generic service interface / no WSDL
                QName serviceName = desc.getServiceName();
                if( serviceName == null ) {
                    // ServiceFactory API requires a service-name.
                    // However, 109 does not allow getServiceName() to be
                    // called, so it's ok to use a dummy value.
                    serviceName = new QName("urn:noservice", "servicename");
                }
                ServiceFactory serviceFac = ServiceFactory.newInstance();
                serviceDelegate = serviceFac.createService(serviceName);
            }

            // Create a proxy for the service object.
            // Get a proxy only in jaxrpc case because in jaxws the service class is not
            // an interface any more
            InvocationHandler handler = null;
            if(serviceDelegate != null) {

                handler = new ServiceInvocationHandler(desc, serviceDelegate, cl);
                returnObj = Proxy.newProxyInstance
                        (cl, new Class[] { serviceInterfaceClass }, handler);
            } else if(jaxwsDelegate != null) {
                returnObj = jaxwsDelegate;
            } else if(injValue != null) {
                returnObj = injValue;
            }
        } catch(PrivilegedActionException pae) {
            logger.log(Level.WARNING, LogUtils.EXCEPTION_THROWN, pae);
            NamingException ne = new NamingException();
            ne.initCause(pae.getCause());
            throw ne;
        } catch(Exception e) {
            logger.log(Level.WARNING, LogUtils.EXCEPTION_THROWN, e);
            NamingException ne = new NamingException();
            ne.initCause(e);
            throw ne;
        } finally {
            WSContainerResolver.unset();
        }

        return returnObj;
    }

    private Object initiateInstance(Class svcClass, ServiceReferenceDescriptor desc)
            throws Exception {

        //TODO BM if JBI needs this reenable it
        /*com.sun.enterprise.webservice.ServiceRefDescUtil descUtil =
           new com.sun.enterprise.webservice.ServiceRefDescUtil();
        descUtil.preServiceCreate(desc);*/
        WsUtil wsu = new WsUtil();
        URL wsdlFile = wsu.privilegedGetServiceRefWsdl(desc);
        /* TODO BM resolve catalog
        // Check if there is a catalog for this web service client
        // If so resolve the catalog entry
        String genXmlDir;
        if(desc.getBundleDescriptor().getApplication() != null) {
            genXmlDir = desc.getBundleDescriptor().getApplication().getGeneratedXMLDirectory();
            if(!desc.getBundleDescriptor().getApplication().isVirtual()) {
                String subDirName = desc.getBundleDescriptor().getModuleDescriptor().getArchiveUri();
                genXmlDir += (File.separator+subDirName.replaceAll("\\.",  "_"));
            }
        } else {
            // this is the case of an appclient being run as class file from command line
            genXmlDir = desc.getBundleDescriptor().getModuleDescriptor().getArchiveUri();
        }
        File catalogFile = new File(genXmlDir,
                desc.getBundleDescriptor().getDeploymentDescriptorDir() +
                    File.separator + "jax-ws-catalog.xml");

        if(catalogFile.exists()) {
            wsdlFile = wsu.resolveCatalog(catalogFile, desc.getWsdlFileUri(), null);
        }   */


        Object obj = null ;

        java.lang.reflect.Constructor cons = svcClass.getConstructor
                (new Class[]{java.net.URL.class,
                        javax.xml.namespace.QName.class});
        try {
            obj =
                    cons.newInstance(wsdlFile, desc.getServiceName());
        } catch (Exception e) {
            /*
             * If WSDL URL is not accessible over http, trying to get an instance via
             * reflection results in InvocationTargetException. If InvocationTargetException
             * is thrown,then catch the exception and generate wsdl in generated xml directory
             * of the application being deployed.
             */
            if (e instanceof InvocationTargetException) {
                URL optionalWsdlURL = generateWsdlFile(desc);
                if (optionalWsdlURL == null)
                    throw e;
                obj = cons.newInstance(optionalWsdlURL, desc.getServiceName());
            }
        }



        /*TODO BM if jbi needs this reenable it
        descUtil.postServiceCreate();
        */
        return obj;

    }



    /**
     * This method returns the location where optional wsdl file will be generated.
     * The directory will be a directory having same name as WebService name inside
     * application's generated xml directory. The name of the wsdl file will be
     * wsdl.xml e.g. if application name is test and service name is Translator,
     * then the location of wsdl will be
     * $Glassfish_home/domains/domain1/generated/xml/test/Translator/wsdl.xml
     *
     * @param desc ServiceReferenceDescriptor
     * @return optional wsdl file location
     */
    private File getOptionalWsdlLocation(ServiceReferenceDescriptor desc) {
        File generatedXmlDir = serverEnv.getApplicationGeneratedXMLPath();
        return new File(new File(new File(generatedXmlDir,
                VersioningUtils.getRepositoryName(desc.getBundleDescriptor().getApplication()
                        .getRegistrationName())), desc.getServiceLocalPart()), "wsdl.xml");
    }

    private void createParentDirs(File optionalWsdlLocation) throws IOException {
        File parent = optionalWsdlLocation.getParentFile();
        mkDirs(parent);
    }

    private URL generateWsdlFile(ServiceReferenceDescriptor desc) throws IOException {

       /*
        * Following piece of code is basically a copy-paste from JAXWSServlet's
        * doGet method (line 230) and from com.sun.xml.ws.transport.http.servlet.HttpAdapter's
        * publishWSDL method (line 587).This piece of code is not completely clear to me,
        * what I have understood so far is, during WSEndPoint creation on line 267 in
        * WSServletContextListener, com.sun.xml.ws.server.EndPointFactory.create (line 116)
        * method is invoked where ServiceDocumentImpl instance is created, which is later
        * being fetched here to generate wsdl. When serviceDefinition.getPrimary() is
        * invoked, basically it returns the reference to wsdl document marked as primary
        * wsdl inside ServiceDefinition. Probably we can directly fetch this wsdl
        * but for now I will go with the way it has been implemented in HttpAdapter.
        */

        File optionalWsdl = getOptionalWsdlLocation(desc);

        /*
         * Its possible that in a given application there are more than one Filter/Servlet
         * with loadOnStartup=1 having WebServiceRef annotation,or WebServiceRef
         * annotation is used at multiple places within the same Filter/Servlet,
         * in which case, when processing is going on for second filter/servlet
         * or annotation referring to the same web service, then wsdl file has
         * already been generated at this point in time and there is no need to
         * generate it again.
         */

        if (optionalWsdl.exists())
            return optionalWsdl.toURI().toURL();

        createParentDirs(optionalWsdl);
        ServletAdapter targetEndpoint = getServletAdapter(desc);
        if (targetEndpoint == null)
            return null;
        ServiceDefinition serviceDefinition = targetEndpoint.getServiceDefinition();
        Iterator wsdlnum = serviceDefinition.iterator();
        SDDocument wsdlDocument = null;
        while (wsdlnum.hasNext()) {
            SDDocument xsdnum = (SDDocument) wsdlnum.next();
            if (xsdnum == serviceDefinition.getPrimary()) {
                wsdlDocument = xsdnum;
                break;
            }
        }

        if (wsdlDocument == null)
            return null;

        OutputStream outputStream = null;
        try {
            outputStream = new BufferedOutputStream(new FileOutputStream(optionalWsdl));
            PortAddressResolver portAddressResolver = targetEndpoint
                    .getPortAddressResolver(getBaseAddress(desc.getWsdlFileUrl()));
            DocumentAddressResolver resolver = targetEndpoint.getDocumentAddressResolver(portAddressResolver);
            wsdlDocument.writeTo(portAddressResolver, resolver, outputStream);
        } finally {
            if (outputStream != null)
                outputStream.close();
        }

        return optionalWsdl.toURI().toURL();
    }

    /**
     * Returns ServletAdapter instance holding wsdl for the WebService being referred
     * in WebServiceRef annotation.
     *
     * @param desc ServiceReferenceDescriptor
     * @return ServletAdapter instance having wsdl contents.
     */
    private ServletAdapter getServletAdapter(ServiceReferenceDescriptor desc) {

        WebBundleDescriptor webBundle = null;
        WebServicesDescriptor webServicesDescriptor = null;

        /*
         * If flow has reached to this part of the code,then in all likelihood,
         * the wsdl is available under the context root of the a web application
         * and hence the BundleDescriptor being referred in ServiceReferenceDescriptor
         * is an instance of WebBundleDescriptor.
         */

        if (desc.getBundleDescriptor() instanceof WebBundleDescriptor) {

            webBundle = ((WebBundleDescriptor) desc.getBundleDescriptor());

        } else {

            /*
             * If above assumption is not true, then make one last attempt to fetch
             * all required params from the wsdl url stored in ServiceReferenceDescriptor.
             */

            return getServletAdapterBasedOnWsdlUrl(desc);
        }

        /*
         * Get WebServicesDescriptor from WebBundleDescriptorImpl, Since we are
         * dealing with WebServiceRef annotation here, WebServicesDescriptor ought to have
         * reference to WebService in question. WebServicesDescriptor is never null as it
         * is being initialized at class level in BundleDescriptor.
         */

        WebServicesDescriptor wsDesc = webBundle.getWebServices();

        assert wsDesc != null;

        /*
         * WebService name is being fetched by invoking getServiceLocalPart()
         * on ServiceReferenceDescriptor. ServiceLocalPart is set when WebServiceClient
         * annotated class is processed inside
         * org.glassfish.webservices.connector.annotation.handlers.WebServiceRefHandler's
         * processAWsRef call (line 339). WebServiceClient annotation have name param pointing
         * to webservice in question.
         */

        assert desc.getServiceLocalPart() != null;

        WebService webService = wsDesc.getWebServiceByName(desc.getServiceLocalPart());

        /*
         * If an unlikely event when there is no associated webService or desc.getServiceLocalPart()
         * itself is null, then fall back on fetching ServletAdapter based on wsdl url.
         */
        if (webService == null)
            return getServletAdapterBasedOnWsdlUrl(desc);

        String contextRoot = webBundle.getContextRoot();
        String webSevicePath = null;
        String publishingContext = null;
        /*
         * Iterate over all associated WebServiceEndPoints for this WebService
         * and break when condition specified in if block is met. This is the same
         * condition based on which wsdl url is set in first place for this
         * ServiceReferenceDescriptor and hence this must hold true in this context too.
         */

        for (WebServiceEndpoint endpoint : webService.getEndpoints()) {
            if (desc.getServiceName().equals(endpoint.getServiceName())
                    && desc.getServiceNamespaceUri().equals(endpoint.getWsdlService().getNamespaceURI())) {
                String endPointAddressURI = endpoint.getEndpointAddressUri();
                if (endPointAddressURI == null || endPointAddressURI.length() == 0)
                    return null;
                webSevicePath = endPointAddressURI.startsWith("/") ? endPointAddressURI : ("/" + endPointAddressURI);
                publishingContext = "/" + endpoint.getPublishingUri() + "/" + webService.getWsdlFileUri();
                Adapter adapter = JAXWSAdapterRegistry.getInstance()
                        .getAdapter(contextRoot, webSevicePath, publishingContext);
                return adapter instanceof ServletAdapter ? (ServletAdapter) adapter : null;

            }
        }
        return null;
    }


    /**
     * This method basically is a fall back mechanism to fetch required
     * parameters from wsdl url stored in ServiceReferenceDescriptor. The flow reaches
     * here only in case where required parameters could not be fetched
     * from WebBundleDescriptor.
     *
     * @param desc ServiceReferenceDescriptor
     * @return ServletAdapter instance having wsdl contents.
     */
    private ServletAdapter getServletAdapterBasedOnWsdlUrl(ServiceReferenceDescriptor desc) {

        if (logger.isLoggable(Level.INFO)) {
            logger.log(Level.INFO, LogUtils.SERVLET_ADAPTER_BASED_ON_WSDL_URL,
                    new Object[]{desc.getServiceLocalPart(), desc.getWsdlFileUrl()});
        }

        URL wsdl = desc.getWsdlFileUrl();
        String wsdlPath = wsdl.getPath().trim();
        if (!wsdlPath.contains(WebServiceEndpoint.PUBLISHING_SUBCONTEXT))
            return null;

         /*
          * WsdlPath indeed contains the WebServiceEndpoint.PUBLISHING_SUBCONTEXT,
          * e.g.assuming that context root is test and Service name is Translator
          * then wsdl url must be in the following format :
          * /test/Translator/__container$publishing$subctx/null?wsdl
          */

        String contextRootAndPath = wsdlPath.substring(1,
                wsdlPath.indexOf(WebServiceEndpoint.PUBLISHING_SUBCONTEXT) - 1); // test/Translator
        if (!(contextRootAndPath.length() > 0))
            return null;
        String[] contextRootAndPathArray = contextRootAndPath.split("/"); // {test, Translator}
        if (contextRootAndPathArray.length != 2)
            return null;
        if (contextRootAndPathArray[0] == null)
            return null;
        String contextRoot = "/" + contextRootAndPathArray[0];  // /test
        if (contextRootAndPathArray[1] == null)
            return null;
        String webSevicePath = "/" + contextRootAndPathArray[1]; // /Translator
        String urlPattern = wsdlPath.substring(contextRoot.length());
        Adapter adapter = JAXWSAdapterRegistry.getInstance()
                .getAdapter(contextRoot, webSevicePath, urlPattern);
        return adapter instanceof ServletAdapter ? (ServletAdapter) adapter : null;

    }

    private static String getBaseAddress(URL wsdlUrl) {
        return wsdlUrl.getProtocol() + "://" + wsdlUrl.getHost() + ":" + wsdlUrl.getPort();
    }

    private void mkDirs(File f) {
        if (!f.mkdirs() && logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, LogUtils.DIR_EXISTS, f);
        }
    }




    private ArrayList getWebServiceFeatures(ServiceReferenceDescriptor desc) {
         /**
         * JAXWS 2.2 enables @MTOM, @Addressing @RespectBinding
         * on WebServiceRef
         * If these are present use the
         * Service(url,wsdl,features) constructor
         */
        ArrayList wsFeatures = new ArrayList();
        if (desc.isMtomEnabled()) {
            wsFeatures.add( new MTOMFeature(true,desc.getMtomThreshold()))   ;
        }
        com.sun.enterprise.deployment.Addressing add = desc.getAddressing();
        if (add != null) {
            wsFeatures.add( new AddressingFeature(
                    add.isEnabled(),add.isRequired(),getResponse(add.getResponses())))   ;
        }
        com.sun.enterprise.deployment.RespectBinding rb = desc.getRespectBinding();
        if (rb != null) {
            wsFeatures.add( new RespectBindingFeature(rb.isEnabled()))   ;
        }
        Map, Annotation> otherAnnotations =
            desc.getOtherAnnotations();
        Iterator it = otherAnnotations.values().iterator();
        while(it.hasNext()){
            wsFeatures.add(getWebServiceFeatureBean((Annotation)it.next()));
        }
        
        return wsFeatures;
    }

    private AddressingFeature.Responses getResponse(String s) {
       if (s != null) {
            return AddressingFeature.Responses.valueOf(AddressingFeature.Responses.class,s);
        } else return AddressingFeature.Responses.ALL;
        
    }

    private void resolvePortComponentLinks(ServiceReferenceDescriptor desc)
            throws Exception {

        // Resolve port component links to target endpoint address.
        // We can't assume web service client is running in same VM
        // as endpoint in the intra-app case because of app clients.
        //
        // Also set port-qname based on linked port's qname if not
        // already set.
        for(Iterator iter = desc.getPortsInfo().iterator(); iter.hasNext();) {
            ServiceRefPortInfo portInfo = (ServiceRefPortInfo) iter.next();

            if( portInfo.isLinkedToPortComponent() ) {
                WebServiceEndpoint linkedPortComponent =
                        portInfo.getPortComponentLink();

                // XXX-JD we could at this point try to figure out the
                // endpoint-address from the ejb wsdl file but it is a
                // little complicated so I will leave it for post Beta2
                if( !(portInfo.hasWsdlPort()) ) {
                    portInfo.setWsdlPort(linkedPortComponent.getWsdlPort());
                }
            }
        }
    }

    private  WebServiceFeature getWebServiceFeatureBean(Annotation a) {
        WebServiceFeatureAnnotation wsfa = a.annotationType().getAnnotation(WebServiceFeatureAnnotation.class);

        Class beanClass = wsfa.bean();
        WebServiceFeature bean;

        Constructor ftrCtr = null;
        String[] paramNames = null;
        for (Constructor con : beanClass.getConstructors()) {
            FeatureConstructor ftrCtrAnn = (FeatureConstructor) con.getAnnotation(FeatureConstructor.class);
            if (ftrCtrAnn != null) {
                if (ftrCtr == null) {
                    ftrCtr = con;
                    paramNames = ftrCtrAnn.value();
                } else {
                    throw new WebServiceException(ModelerMessages.RUNTIME_MODELER_WSFEATURE_MORETHANONE_FTRCONSTRUCTOR(a, beanClass));
                }
            }
        }
        if (ftrCtr == null) {
            throw new WebServiceException(ModelerMessages.RUNTIME_MODELER_WSFEATURE_NO_FTRCONSTRUCTOR(a, beanClass));
        }
        if (ftrCtr.getParameterTypes().length != paramNames.length) {
            throw new WebServiceException(ModelerMessages.RUNTIME_MODELER_WSFEATURE_ILLEGAL_FTRCONSTRUCTOR(a, beanClass));
        }

        try {
            Object[] params = new Object[paramNames.length];
            for (int i = 0; i < paramNames.length; i++) {
                Method m = a.annotationType().getDeclaredMethod(paramNames[i]);
                params[i] = m.invoke(a);
            }
            bean = (WebServiceFeature) ftrCtr.newInstance(params);
        } catch (Exception e) {
            throw new WebServiceException(e);
        }

        return bean;
    }


}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy