Package org.apache.geronimo.jaxws.builder

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

/**
*  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.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLLocator;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceClient;

import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.j2ee.deployment.Module;
import org.apache.geronimo.jaxws.JAXWSUtils;
import org.apache.geronimo.jaxws.client.EndpointInfo;
import org.apache.geronimo.jaxws.wsdl.CatalogJarWSDLLocator;
import org.apache.geronimo.jaxws.wsdl.CatalogWSDLLocator;
import org.apache.geronimo.xbeans.geronimo.naming.GerPortPropertyType;
import org.apache.geronimo.xbeans.geronimo.naming.GerPortType;
import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefType;
import org.apache.geronimo.xbeans.javaee6.PortComponentRefType;
import org.apache.xml.resolver.Catalog;
import org.apache.xml.resolver.CatalogManager;
import org.apache.xml.resolver.tools.CatalogResolver;

import org.osgi.framework.Bundle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EndpointInfoBuilder {

    private static final Logger LOG = LoggerFactory.getLogger(EndpointInfoBuilder.class);

    private Module module;

    private Bundle bundle;

    private URI wsdlURI;

    private QName serviceQName;

    private Class serviceClass;

    private GerServiceRefType serviceRefType;

    private Map<Object, EndpointInfo> portInfoMap = new HashMap<Object, EndpointInfo>();

    private Map<Class, PortComponentRefType> portComponentRefMap;

    public EndpointInfoBuilder(Class serviceClass,
                               GerServiceRefType serviceRefType,
                               Map<Class, PortComponentRefType> portComponentRefMap,
                               Module module,
                               Bundle bundle,
                               URI wsdlURI,
                               QName serviceQName) {
        this.serviceClass = serviceClass;
        this.serviceRefType = serviceRefType;
        this.portComponentRefMap = portComponentRefMap;
        this.module = module;
        this.bundle = bundle;
        this.wsdlURI = wsdlURI;
        this.serviceQName = serviceQName;
    }

    public URI getWsdlURI() {
        return this.wsdlURI;
    }

    public QName getServiceQName() {
        return this.serviceQName;
    }

    public Map<Object, EndpointInfo> getEndpointInfo() {
        return this.portInfoMap;
    }

    public void build() throws DeploymentException {
        if (this.wsdlURI == null) {
            // wsdl was not explicitly specified
            if (javax.xml.ws.Service.class.equals(this.serviceClass)) {
                // Generic Service class specified.
                // Service API requires a service qname so create a dummy one
                this.serviceQName = new QName("http://noservice", "noservice");

                if (serviceRefType != null) {
                    for (GerPortType gerPort : serviceRefType.getPortArray()) {
                        String portName = gerPort.getPortName().trim();
                        URL location = getLocation(gerPort);
                        String credentialsName = getCredentialsName(gerPort);
                        boolean mtomEnabled = isMTOMEnabled(portName);
                        Map<String, Object> props = getProperties(gerPort);
                        EndpointInfo info = new EndpointInfo(location, credentialsName, mtomEnabled, props);
                        this.portInfoMap.put(portName, info);
                    }
                }

                return;
            } else {
                // Generated Service class specified.
                // Get the wsdl and service qname from the WebServiceClient annotation
                // of the generated Service class
                WebServiceClient webServiceClient =
                    (WebServiceClient) this.serviceClass.getAnnotation(WebServiceClient.class);
                if (webServiceClient != null) {
                    this.wsdlURI = getWSDLLocation(webServiceClient);
                    this.serviceQName = getServiceQName(webServiceClient);
                }

                // wsdl really shouldn't be null at this point
                if (this.wsdlURI == null) {
                    return;
                }
            }
        }

        Catalog catalog = loadCatalog();

        WSDLLocator wsdlLocator = null;
        if (isURL(this.wsdlURI.toString())) {
            wsdlLocator = new CatalogWSDLLocator(this.wsdlURI.toString(), catalog);
        } else {
            wsdlLocator = new CatalogJarWSDLLocator(this.module.getModuleFile(), this.wsdlURI, catalog);
        }

        Definition definition;
        WSDLFactory wsdlFactory;
        try {
            wsdlFactory = WSDLFactory.newInstance();
        } catch (WSDLException e) {
            throw new DeploymentException("Could not create WSDLFactory", e);
        }
        WSDLReader wsdlReader = wsdlFactory.newWSDLReader();
        wsdlReader.setFeature("javax.wsdl.importDocuments", true);
        wsdlReader.setFeature("javax.wsdl.verbose", false);
        try {
            definition = wsdlReader.readWSDL(wsdlLocator);
        } catch (WSDLException e) {
            throw new DeploymentException("Failed to read wsdl document", e);
        } catch (RuntimeException e) {
            throw new DeploymentException(e.getMessage(), e);
        }

        verifyPortComponentList(definition);

        Map services = definition.getServices();
        if (services.size() == 0) {
            // partial wsdl, return as is

            if (this.serviceRefType != null && this.serviceRefType.isSetServiceCompletion()) {
                LOG.warn("Service completion is not supported with partial wsdl");
            }
        } else {
            // full wsdl

            if (this.serviceRefType != null && this.serviceRefType.isSetServiceCompletion()) {
                throw new DeploymentException("Full wsdl, but service completion supplied");
            }

            Service service = null;
            if (this.serviceQName != null) {
                service = definition.getService(this.serviceQName);
                if (service == null) {
                    throw new DeploymentException(
                            "No service wsdl for supplied service qname "
                                    + this.serviceQName);
                }
            } else if (services.size() == 1) {
                service = (Service) services.values().iterator().next();
                this.serviceQName = service.getQName();
            } else {
                throw new DeploymentException(
                        "No service qname supplied, and there are "
                                + services.size() + " services");
            }

            // organize the extra port info
            Map<String, GerPortType> portMap = new HashMap<String, GerPortType>();
            if (serviceRefType != null) {
                GerPortType[] ports = serviceRefType.getPortArray();
                for (int i = 0; i < ports.length; i++) {
                    GerPortType port = ports[i];
                    String portName = port.getPortName().trim();
                    portMap.put(portName, port);
                }
            }

            Map wsdlPortMap = service.getPorts();
            for (Iterator iterator = wsdlPortMap.entrySet().iterator(); iterator.hasNext();) {
                Map.Entry entry = (Map.Entry) iterator.next();
                String portName = (String) entry.getKey();
                Port port = (Port) entry.getValue();

                GerPortType gerPort = portMap.get(portName);

                URL location = (gerPort == null) ? getAddressLocation(port) : getLocation(gerPort);
                // skip non-soap ports
                if (location == null) {
                    continue;
                }
                String credentialsName = (gerPort == null) ? null : getCredentialsName(gerPort);

                Binding binding = port.getBinding();
                if (binding == null) {
                    throw new DeploymentException("No binding for port: " + portName);
                }

                PortType portType = binding.getPortType();
                if (portType == null) {
                    throw new DeploymentException("No portType for binding: " + binding.getQName());
                }

                boolean mtomEnabled = isMTOMEnabled(portType.getQName());

                Map<String, Object> props = getProperties(gerPort);

                EndpointInfo info = new EndpointInfo(location, credentialsName, mtomEnabled, props);
                this.portInfoMap.put(portName, info);
                // prefer first binding listed in wsdl
                if (!this.portInfoMap.containsKey(portType.getQName())) {
                    this.portInfoMap.put(portType.getQName(), info);
                }
            }
        }
    }

    private QName getServiceQName(WebServiceClient webServiceClient) {
        if (webServiceClient.targetNamespace() != null && webServiceClient.name() != null) {
            return new QName(webServiceClient.targetNamespace(), webServiceClient.name());
        } else {
            return null;
        }
    }

    private URI getWSDLLocation(WebServiceClient webServiceClient) throws DeploymentException {
        String wsdlLocation = webServiceClient.wsdlLocation();
        if (wsdlLocation != null && wsdlLocation.trim().length() > 0) {
            try {
                return new URI(wsdlLocation.trim());
            } catch (URISyntaxException e) {
                throw new DeploymentException(
                        "Invalid wsdl location in annotation: " + wsdlLocation, e);
            }
        }

        return null;
    }

    private Map<String, Object> getProperties(GerPortType port) {
        Map<String, Object> props = new HashMap<String, Object>();
        if (port != null && port.getPropertyArray() != null) {
            for (GerPortPropertyType propertyType : port.getPropertyArray()) {
                props.put(propertyType.getName(), propertyType.getStringValue().trim());
            }
        }
        return props;
    }

    private String getCredentialsName(GerPortType port) {
        String credentialsName = port.getCredentialsName();
        return (credentialsName == null) ? null : credentialsName.trim();
    }

    private URL getLocation(GerPortType port) throws DeploymentException {
        String protocol = port.getProtocol().trim();
        String host = port.getHost().trim();
        int portNum = port.getPort();
        String uri = port.getUri().trim();
        String locationURIString = protocol + "://" + host + ":" + portNum + uri;
        URL location = getURL(locationURIString);
        return location;
    }

    private URL getAddressLocation(Port port) throws DeploymentException {
        SOAPAddress soapAddress =
            (SOAPAddress) getExtensibilityElement(SOAPAddress.class, port.getExtensibilityElements());
        URL location = null;
        if (soapAddress != null) {
            String locationURIString = soapAddress.getLocationURI();
            location = getURL(locationURIString);
        }
        return location;
    }

    private URL getURL(String locationURIString) throws DeploymentException {
        try {
            return new URL(locationURIString);
        } catch (MalformedURLException e) {
            throw new DeploymentException(
                    "Could not construct web service location URL from "
                            + locationURIString, e);
        }
    }

    public static ExtensibilityElement getExtensibilityElement(Class clazz,
                                                               List extensibilityElements) {
        for (Iterator iterator = extensibilityElements.iterator(); iterator
                .hasNext();) {
            ExtensibilityElement extensibilityElement = (ExtensibilityElement) iterator
                    .next();
            if (clazz.isAssignableFrom(extensibilityElement.getClass())) {
                return extensibilityElement;
            }
        }
        return null;
    }

    private void verifyPortComponentList(Definition wsdl) throws DeploymentException {
        if (this.portComponentRefMap == null) {
            return;
        }
        for (Class sei : this.portComponentRefMap.keySet()) {
            QName portType = JAXWSUtils.getPortType(sei);
            if (portType == null) {
                continue;
            }
            if (wsdl.getPortType(portType) == null) {
                throw new DeploymentException("No portType found in WSDL for SEI: " + sei.getName());
            }
        }
    }

    private boolean isMTOMEnabled(QName portType) {
        boolean mtomEnabled = false;
        PortComponentRefType portRef = getPortComponentRef(portType);
        if (portRef != null && portRef.isSetEnableMtom()) {
            mtomEnabled = portRef.getEnableMtom().getBooleanValue();
        }
        return mtomEnabled;
    }

    private PortComponentRefType getPortComponentRef(QName portType) {
        if (this.portComponentRefMap == null) {
            return null;
        }
        for (Class sei : this.portComponentRefMap.keySet()) {
            QName seiPortType = JAXWSUtils.getPortType(sei);
            if (seiPortType == null) {
                continue;
            }
            if (portType.equals(seiPortType)) {
                return this.portComponentRefMap.get(sei);
            }
        }
        return null;
    }

    private boolean isMTOMEnabled(String portName) {
        boolean mtomEnabled = false;
        PortComponentRefType portRef = getPortComponentRef(portName);
        if (portRef != null && portRef.isSetEnableMtom()) {
            mtomEnabled = portRef.getEnableMtom().getBooleanValue();
        }
        return mtomEnabled;
    }

    private PortComponentRefType getPortComponentRef(String portName) {
        if (this.portComponentRefMap == null) {
            return null;
        }
        for (Class sei : this.portComponentRefMap.keySet()) {
            QName seiPortType = JAXWSUtils.getPortType(sei);
            if (seiPortType == null) {
                continue;
            }
            if (portName.equals(seiPortType.getLocalPart())) {
                return this.portComponentRefMap.get(sei);
            }
        }
        return null;
    }

    private boolean isURL(String name) {
        try {
            new URL(name);
            return true;
        } catch (MalformedURLException e1) {
            return false;
        }
    }

    private Catalog loadCatalog() {
        URL catalogURI = null;
        try {
            catalogURI = getCatalog(JAXWSUtils.DEFAULT_CATALOG_WEB);
            if (catalogURI == null) {
                catalogURI = getCatalog(JAXWSUtils.DEFAULT_CATALOG_EJB);
            }
        } catch (IOException e) {
            LOG.warn("Failed to open OASIS catalog", e);
        }

        CatalogManager catalogManager = new CatalogManager();
        catalogManager.setUseStaticCatalog(false);
        catalogManager.setIgnoreMissingProperties(true);
        CatalogResolver catalogResolver = new CatalogResolver(catalogManager);
        Catalog catalog = catalogResolver.getCatalog();

        if (catalogURI != null) {
            LOG.debug("Found OASIS catalog {} ", catalogURI);
            try {
                catalog.parseCatalog(catalogURI);
            } catch (Exception e) {
                LOG.warn("Failed to read OASIS catalog", e);
            }
        }

        return catalog;
    }

    private URL getCatalog(String name) throws IOException {
        URL catalogURL = this.bundle.getResource(name);
        if (catalogURL == null) {
            File f = this.module.getEarContext().getTargetFile(URI.create(name));
            if (f.exists()) {
                catalogURL = f.toURI().toURL();
            }
        }
        return catalogURL;
    }

}
TOP

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

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.