Package org.apache.geronimo.jaxws.builder

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

/**
*  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.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.jaxws.JAXWSUtils;
import org.apache.geronimo.jaxws.client.EndpointInfo;
import org.apache.geronimo.xbeans.geronimo.naming.GerPortType;
import org.apache.geronimo.xbeans.geronimo.naming.GerServiceRefType;
import org.xml.sax.InputSource;

public class EndpointInfoBuilder {

    private static final Log LOG = LogFactory.getLog(EndpointInfoBuilder.class);

    private JarFile moduleFile;

    private URI wsdlURI;

    private QName serviceQName;

    private Class serviceClass;

    private GerServiceRefType serviceRefType;

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

    private Map<Class, String> portComponentRefMap;

    public EndpointInfoBuilder(Class serviceClass,
                               GerServiceRefType serviceRefType,
                               Map<Class, String> portComponentRefMap,
                               JarFile moduleFile,
                               URI wsdlURI,
                               QName serviceQName) {
        this.serviceClass = serviceClass;
        this.serviceRefType = serviceRefType;
        this.portComponentRefMap = portComponentRefMap;
        this.moduleFile = moduleFile;
        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 explitely not specified, try to get it from
            // the service class annotation
            WebServiceClient webServiceClient =
                (WebServiceClient) this.serviceClass.getAnnotation(WebServiceClient.class);
            if (webServiceClient != null) {
                this.wsdlURI = getWSDLLocation(webServiceClient);              
                this.serviceQName = getServiceQName(webServiceClient);
            }
          
            if (this.wsdlURI == null) {               
                return;
            }
        }
       
        JarWSDLLocator wsdlLocator = null;
        URL wsdlURL = null;
        try {
            wsdlURL = new URL(this.wsdlURI.toString());
        } catch (MalformedURLException e1) {
            // not a URL, assume it's a local reference
            wsdlLocator = new JarWSDLLocator(this.wsdlURI);
        }

        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", false);
        try {
            if (wsdlURL != null) {
                definition = wsdlReader.readWSDL(wsdlURL.toString());
            } else if (wsdlLocator != null) {
                definition = wsdlReader.readWSDL(wsdlLocator);
            } else {
                throw new DeploymentException("unknown");
            }
        } 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());
                }

                EndpointInfo info = new EndpointInfo(location, credentialsName);
                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) {
            try {
                return new URI(wsdlLocation);
            } catch (URISyntaxException e) {
                throw new DeploymentException(
                        "Invalid wsdl location in annotation: " + wsdlLocation);
            }
        }

        return null;
    }

    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);
        }
    }
   
    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 class JarWSDLLocator implements WSDLLocator {

        private final List<InputStream> streams = new ArrayList<InputStream>();

        private final URI wsdlURI;

        private URI latestImportURI;

        public JarWSDLLocator(URI wsdlURI) {
            this.wsdlURI = wsdlURI;
        }

        public InputSource getBaseInputSource() {
            InputStream wsdlInputStream;
            ZipEntry entry = moduleFile.getEntry(wsdlURI.toString());
            if (entry == null) {
                throw new RuntimeException(
                        "WSDL file does not exist in the module " + wsdlURI.toString());
            }
            try {
                wsdlInputStream = moduleFile.getInputStream(entry);
                streams.add(wsdlInputStream);
            } catch (Exception e) {
                throw new RuntimeException(
                        "Could not open stream to wsdl file", e);
            }
            return new InputSource(wsdlInputStream);
        }

        public String getBaseURI() {
            return wsdlURI.toString();
        }

        public InputSource getImportInputSource(String parentLocation,
                                                String relativeLocation) {
            URI parentURI = URI.create(parentLocation);
            latestImportURI = parentURI.resolve(relativeLocation);
            InputStream importInputStream;
            ZipEntry entry = moduleFile.getEntry(latestImportURI.toString());
            if (entry == null) {
                throw new RuntimeException(
                        "File does not exist in the module " + latestImportURI.toString());
            }
            try {               
                importInputStream = moduleFile.getInputStream(entry);
                streams.add(importInputStream);
            } catch (Exception e) {
                throw new RuntimeException(
                        "Could not open stream to import file", e);
            }
            InputSource inputSource = new InputSource(importInputStream);
            inputSource.setSystemId(getLatestImportURI());
            return inputSource;
        }

        public String getLatestImportURI() {
            return latestImportURI.toString();
        }

        public void close() {
            for (InputStream inputStream : this.streams) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    // ignore
                }
            }
            streams.clear();
        }
    }
}
TOP

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

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.