Package org.apache.geronimo.jaxws.builder

Source Code of org.apache.geronimo.jaxws.builder.JAXWSServiceBuilder

/**
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/

package org.apache.geronimo.jaxws.builder;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBException;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.soap.AddressingFeature;

import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.deployment.Deployable;
import org.apache.geronimo.deployment.DeploymentContext;
import org.apache.geronimo.deployment.service.EnvironmentBuilder;
import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.j2ee.annotation.Holder;
import org.apache.geronimo.j2ee.deployment.EARContext;
import org.apache.geronimo.j2ee.deployment.Module;
import org.apache.geronimo.j2ee.deployment.NamingBuilder;
import org.apache.geronimo.j2ee.deployment.WebModule;
import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
import org.apache.geronimo.jaxws.JAXWSEJBApplicationContext;
import org.apache.geronimo.jaxws.JAXWSUtils;
import org.apache.geronimo.jaxws.JAXWSWebApplicationContext;
import org.apache.geronimo.jaxws.PortInfo;
import org.apache.geronimo.jaxws.annotations.AnnotationHolder;
import org.apache.geronimo.jaxws.feature.AddressingFeatureInfo;
import org.apache.geronimo.jaxws.feature.MTOMFeatureInfo;
import org.apache.geronimo.jaxws.feature.RespectBindingFeatureInfo;
import org.apache.geronimo.jaxws.handler.HandlerChainsInfoBuilder;
import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
import org.apache.geronimo.kernel.GBeanNotFoundException;
import org.apache.geronimo.kernel.repository.Environment;
import org.apache.geronimo.kernel.util.IOUtils;
import org.apache.openejb.jee.Addressing;
import org.apache.openejb.jee.JaxbJavaee;
import org.apache.openejb.jee.PortComponent;
import org.apache.openejb.jee.ServiceImplBean;
import org.apache.openejb.jee.WebserviceDescription;
import org.apache.openejb.jee.Webservices;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class JAXWSServiceBuilder implements WebServiceBuilder {

    private static final Logger LOG = LoggerFactory.getLogger(JAXWSServiceBuilder.class);
   
    private static final boolean JAX_WS_SERVER_SUPPORT;
   
    static {
        String webServiceServerSupported = System.getProperty("org.apache.geronimo.jaxws.server.support");
        if (webServiceServerSupported == null) {
            webServiceServerSupported = System.getProperty("org.apache.geronimo.jaxws.support");
        }
        JAX_WS_SERVER_SUPPORT = webServiceServerSupported == null ? true : Boolean.valueOf(webServiceServerSupported);
    }

    private HandlerChainsInfoBuilder handlerChainsInfoBuilder = new HandlerChainsInfoBuilder();

    protected final Environment defaultEnvironment;
    protected WebServiceFinder webServiceFinder;

    public JAXWSServiceBuilder(Environment defaultEnvironment) {
        this.defaultEnvironment = defaultEnvironment;
    }

    protected void setWebServiceFinder(WebServiceFinder finder) {
        this.webServiceFinder = finder;
    }

    protected String getKey() {
        return getClass().getName();
    }

    @Override
    public void findWebServices(Module module, boolean isEJB, Map<String, String> servletLocations, Environment environment, Map sharedContext) throws DeploymentException {
        if (!JAX_WS_SERVER_SUPPORT) {
            return;
        }
        Map<String, PortInfo> serviceLinkPortInfoMap = discoverWebServices(module, isEJB, servletLocations);
        String path = isEJB ? "META-INF/webservices.xml" : "WEB-INF/webservices.xml";
        Deployable deployable = module.getDeployable();
        URL wsDDUrl = deployable.getResource(path);
        if (wsDDUrl != null) {
            InputStream in = null;
            try {
                in = new BufferedInputStream(wsDDUrl.openStream());

                Webservices wst = (Webservices) JaxbJavaee.unmarshalJavaee(Webservices.class, in);
                for (WebserviceDescription desc : wst.getWebserviceDescription()) {
                    String wsdlFile = null;
                    if (desc.getWsdlFile() != null) {
                        wsdlFile = getString(desc.getWsdlFile());
                    }
                    String serviceName = desc.getWebserviceDescriptionName();
                    for (PortComponent port : desc.getPortComponent()) {

                        String serviceLink = null;
                        ServiceImplBean beanType = port.getServiceImplBean();
                        if (beanType.getEjbLink() != null) {
                            serviceLink = beanType.getEjbLink();
                        } else if (beanType.getServletLink() != null) {
                            serviceLink = beanType.getServletLink();
                        }

                        PortInfo portInfo = serviceLinkPortInfoMap.get(serviceLink);
                        if (portInfo == null) {
                            portInfo = new PortInfo();
                            portInfo.setServiceLink(serviceLink);
                            serviceLinkPortInfoMap.put(serviceLink, portInfo);
                        }

                        if (port.getServiceEndpointInterface() != null) {
                            String sei = port.getServiceEndpointInterface();
                            portInfo.setServiceEndpointInterfaceName(sei);
                        }

                        if (port.getPortComponentName() != null) {
                            portInfo.setPortName(port.getPortComponentName());
                        }

                        if (port.getProtocolBinding() != null) {
                            portInfo.setProtocolBinding(port.getProtocolBinding());
                        }

                        portInfo.setServiceName(serviceName);

                        if (wsdlFile != null) {
                            portInfo.setWsdlFile(wsdlFile);
                        }

                        if (port.getHandlerChains() != null) {
                            portInfo.setHandlerChainsInfo(handlerChainsInfoBuilder.build(port.getHandlerChains()));
                        }

                        if (port.getWsdlPort() != null) {
                            portInfo.setWsdlPort(port.getWsdlPort());
                        }

                        if (port.getWsdlService() != null) {
                            portInfo.setWsdlService(port.getWsdlService());
                        }

                        String location = servletLocations.get(serviceLink);
                        portInfo.setLocation(location);

                        Addressing addressing = port.getAddressing();
                        if (addressing != null) {
                            AddressingFeatureInfo addressingFeatureInfo = portInfo.getAddressingFeatureInfo();
                            if (addressingFeatureInfo == null) {
                                addressingFeatureInfo = new AddressingFeatureInfo();
                                portInfo.setAddressingFeatureInfo(addressingFeatureInfo);
                            }
                            if (addressing.getEnabled() != null) {
                                addressingFeatureInfo.setEnabled(addressing.getEnabled());
                            }
                            if (addressing.getRequired() != null) {
                                addressingFeatureInfo.setRequired(addressing.getRequired());
                            }
                            if (addressing.getResponses() != null) {
                                addressingFeatureInfo.setResponses(AddressingFeature.Responses.valueOf(addressing.getResponses().name()));
                            }
                        }

                        if (port.getEnableMtom() != null || port.getMtomThreshold() != null) {
                            MTOMFeatureInfo mtomFeatureInfo = portInfo.getMtomFeatureInfo();
                            if (mtomFeatureInfo == null) {
                                mtomFeatureInfo = new MTOMFeatureInfo();
                                portInfo.setMtomFeatureInfo(mtomFeatureInfo);
                            }
                            if (port.getEnableMtom() != null) {
                                mtomFeatureInfo.setEnabled(port.getEnableMtom());
                            }
                            if (port.getMtomThreshold() != null) {
                                mtomFeatureInfo.setThreshold(port.getMtomThreshold());
                            }
                        }

                        if (port.getRespectBinding() != null && port.getRespectBinding().getEnabled() != null) {
                            RespectBindingFeatureInfo respectBindingFeatureInfo = portInfo.getRespectBindingFeatureInfo();
                            if (respectBindingFeatureInfo == null) {
                                respectBindingFeatureInfo = new RespectBindingFeatureInfo();
                                portInfo.setRespectBindingFeatureInfo(respectBindingFeatureInfo);
                            }
                            respectBindingFeatureInfo.setEnabled(port.getRespectBinding().getEnabled());
                        }
                    }
                }
            } catch (JAXBException e) {
                //we hope it's jax-rpc
                LOG.debug("Descriptor ignored (not a Java EE 5 descriptor)");
            } catch (Exception e) {
                throw new DeploymentException("Failed to parse " + path, e);
            } finally {
                IOUtils.close(in);
            }
        }

        if (serviceLinkPortInfoMap != null && !serviceLinkPortInfoMap.isEmpty()) {
            EnvironmentBuilder.mergeEnvironments(environment, defaultEnvironment);
            sharedContext.put(getKey(), serviceLinkPortInfoMap);
        }
    }

    private String getString(String in) {
        if (in != null) {
            in = in.trim();
            if (in.length() == 0) {
                return null;
            }
        }
        return in;
    }

    private Map<String, PortInfo> discoverWebServices(Module module,
                                                      boolean isEJB,
                                                      Map<String, String> correctedPortLocations)
            throws DeploymentException {
        if (webServiceFinder == null) {
            throw new DeploymentException("WebServiceFinder not configured");
        }
        return webServiceFinder.discoverWebServices(module, correctedPortLocations);
    }

    @Override
    public boolean configurePOJO(GBeanData targetGBean,
                                 String servletName,
                                 Module module,
                                 String servletClassName,
                                 DeploymentContext context)
            throws DeploymentException {
        if (!JAX_WS_SERVER_SUPPORT) {
            return false;
        }
        Map sharedContext = ((WebModule) module).getSharedContext();
        Map<String, PortInfo> portInfoMap = (Map<String, PortInfo>) sharedContext.get(getKey());
        if (portInfoMap == null) {
            // not ours
            return false;
        }
        PortInfo portInfo = portInfoMap.get(servletName);
        if (portInfo == null) {
            // not ours
            return false;
        }

        // verify that the class is loadable and is a JAX-WS web service
        Bundle bundle = context.getDeploymentBundle();
        Class<?> servletClass = loadClass(servletClassName, bundle);
        if (!JAXWSUtils.isWebService(servletClass)) {
            return false;
        }

        Map<String, PortInfo> servletNamePortInfoMap = null;
        AbstractName jaxwsWebApplicationContextName = context.getNaming().createChildName(module.getModuleName(), "JAXWSWebApplicationContext", "JAXWSWebApplicationContext");
        try {
            servletNamePortInfoMap = (Map<String, PortInfo>)(context.getGBeanInstance(jaxwsWebApplicationContextName).getAttribute("servletNamePortInfoMap"));
        } catch (GBeanNotFoundException e) {
            GBeanData jaxwsWebApplicationContextGBeanData = new GBeanData(jaxwsWebApplicationContextName, JAXWSWebApplicationContext.class);
            try {
                context.addGBean(jaxwsWebApplicationContextGBeanData);
            } catch (GBeanAlreadyExistsException e1) {
            }
            servletNamePortInfoMap = new HashMap<String, PortInfo>();
            jaxwsWebApplicationContextGBeanData.setAttribute("servletNamePortInfoMap", servletNamePortInfoMap);
        }
        targetGBean.addDependency(jaxwsWebApplicationContextName);
        servletNamePortInfoMap.put(servletName, portInfo);

        Map componentContext = null;
        Holder moduleHolder = null;
        try {
            //TODO Now we share the same DeploymentContext in the ear package, which means all the gbeans are saved in the one EARContext
            //Might need to update while we have real EAR support
            moduleHolder = (Holder) module.getSharedContext().get(NamingBuilder.INJECTION_KEY);
            GBeanData contextSourceGBean = context.getGBeanInstance(context.getNaming().createChildName(module.getModuleName(), "ContextSource", "ContextSource"));
            componentContext = (Map) contextSourceGBean.getAttribute("componentContext");
        } catch (GBeanNotFoundException e) {
            LOG.warn("ModuleGBean not found. JNDI resource injection will not work.");
        }

        AnnotationHolder serviceHolder =
            (AnnotationHolder)sharedContext.get(WebServiceContextAnnotationHelper.class.getName());
        if (serviceHolder == null) {
            serviceHolder = new AnnotationHolder(moduleHolder);
            sharedContext.put(WebServiceContextAnnotationHelper.class.getName(), serviceHolder);
        }
        WebServiceContextAnnotationHelper.addWebServiceContextInjections(serviceHolder, servletClass);

        String location = portInfo.getLocation();
        LOG.info("Configuring JAX-WS Web Service: " + servletName + " at " + location);

        AbstractName containerFactoryName = context.getNaming().createChildName(targetGBean.getAbstractName(), getContainerFactoryGBeanInfo().getName(), GBeanInfoBuilder.DEFAULT_J2EE_TYPE);
        GBeanData containerFactoryData = new GBeanData(containerFactoryName, getContainerFactoryGBeanInfo());
        containerFactoryData.setAttribute("portInfo", portInfo);
        containerFactoryData.setAttribute("endpointClassName", servletClassName);
        containerFactoryData.setAttribute("componentContext", componentContext);
        containerFactoryData.setAttribute("holder", serviceHolder);
        containerFactoryData.setAttribute("contextRoot", ((WebModule) module).getContextRoot());
        containerFactoryData.setAttribute("catalogName", JAXWSBuilderUtils.normalizeCatalogPath(module, JAXWSUtils.DEFAULT_CATALOG_WEB));
        try {
            context.addGBean(containerFactoryData);
        } catch (GBeanAlreadyExistsException e) {
            throw new DeploymentException("Could not add web service container factory gbean", e);
        }

        targetGBean.setReferencePattern("WebServiceContainerFactory", containerFactoryName);
        // our web container does not use that property
        targetGBean.setAttribute("pojoClassName", "java.lang.Object");

        if (context instanceof EARContext) {
            containerFactoryData.setReferencePattern("TransactionManager",
                                                     ((EARContext)context).getTransactionManagerName());
        }

        initialize(containerFactoryData, servletClass, portInfo, module, bundle);
        return true;
    }

    protected abstract GBeanInfo getContainerFactoryGBeanInfo();

    @Override
    public boolean configureEJB(GBeanData targetGBean,
                                String ejbName,
                                Module module,
                                Map sharedContext,
                                Bundle bundle)
            throws DeploymentException {
        if (!JAX_WS_SERVER_SUPPORT) {
            return false;
        }
        Map<String, PortInfo> portInfoMap = (Map<String, PortInfo>) sharedContext.get(getKey());
        if (portInfoMap == null) {
            // not ours
            return false;
        }
        PortInfo portInfo = portInfoMap.get(ejbName);
        if (portInfo == null) {
            // not ours
            return false;
        }

        String beanClassName = (String)targetGBean.getAttribute("ejbClass");
        // verify that the class is loadable and is a JAX-WS web service
        Class<?> beanClass = loadClass(beanClassName, bundle);
        if (!JAXWSUtils.isWebService(beanClass)) {
            return false;
        }

        String location = portInfo.getLocation();
        if (location == null) {
            throw new DeploymentException("Endpoint URI for EJB WebService is missing");
        }

        Map<String, PortInfo> ejbNamePortInfoMap = null;
        DeploymentContext context = module.getEarContext();
        AbstractName jaxwsEJBApplicationContextName = context.getNaming().createChildName(module.getModuleName(), "JAXWSEJBApplicationContext", "JAXWSEJBApplicationContext");
        try {
            ejbNamePortInfoMap = (Map<String, PortInfo>)(context.getGBeanInstance(jaxwsEJBApplicationContextName).getAttribute("ejbNamePortInfoMap"));
        } catch (GBeanNotFoundException e) {
            GBeanData jaxwsEJBApplicationContextGBeanData = new GBeanData(jaxwsEJBApplicationContextName, JAXWSEJBApplicationContext.class);
            try {
                context.addGBean(jaxwsEJBApplicationContextGBeanData);
            } catch (GBeanAlreadyExistsException e1) {
            }
            ejbNamePortInfoMap = new HashMap<String, PortInfo>();
            jaxwsEJBApplicationContextGBeanData.setAttribute("ejbNamePortInfoMap", ejbNamePortInfoMap);
        }
        targetGBean.addDependency(jaxwsEJBApplicationContextName);
        ejbNamePortInfoMap.put(ejbName, portInfo);

        LOG.info("Configuring EJB JAX-WS Web Service: " + ejbName + " at " + location);

        targetGBean.setAttribute("portInfo", portInfo);

        targetGBean.setAttribute("catalogName", JAXWSBuilderUtils.normalizeCatalogPath(module, JAXWSUtils.DEFAULT_CATALOG_EJB));

        initialize(targetGBean, beanClass, portInfo, module, bundle);

        return true;
    }

    protected void initialize(GBeanData targetGBean, Class wsClass, PortInfo info, Module module, Bundle bundle) throws DeploymentException {
    }

    Class<?> loadClass(String className, Bundle bundle) throws DeploymentException {
        try {
            return bundle.loadClass(className);
        } catch (ClassNotFoundException ex) {
            throw new DeploymentException("Unable to load Web Service class: " + className, ex);
        }
    }

    protected boolean isWsdlSet(PortInfo portInfo, Class serviceClass, Bundle bundle) {
        return (portInfo.getWsdlFile() != null && !portInfo.getWsdlFile().trim().equals("")) || JAXWSUtils.containsWsdlLocation(serviceClass, bundle);
    }

    protected boolean isHTTPBinding(PortInfo portInfo, Class serviceClass) {
        String bindingURI = "";
        String bindingURIFromAnnot;

        if (portInfo.getProtocolBinding() != null) {
            bindingURI = JAXWSUtils.getBindingURI(portInfo.getProtocolBinding());
        }
        bindingURIFromAnnot = JAXWSUtils.getBindingURIFromAnnot(serviceClass);

        if (bindingURI != null && !bindingURI.trim().equals("")) {
            return bindingURI.equals(HTTPBinding.HTTP_BINDING);
        } else if (bindingURIFromAnnot != null && !bindingURIFromAnnot.trim().equals("")) {
            return bindingURIFromAnnot.equals(HTTPBinding.HTTP_BINDING);
        }

        return false;
    }
}
TOP

Related Classes of org.apache.geronimo.jaxws.builder.JAXWSServiceBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.