org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser.java

Source

/*******************************************************************************
 * Copyright (c) 2001, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060504   119296 pmoogk@ca.ibm.com - Peter Moogk
 * 20060517   142324 rsinha@ca.ibm.com - Rupam Kuehner
 * 20060711   150301 pmoogk@ca.ibm.com - Peter Moogk
 * 20060818   154393 pmoogk@ca.ibm.com - Peter Moogk
 * 20060906   156420 pmoogk@ca.ibm.com - Peter Moogk
 * 20121004   385354 kchong@ca.ibm.com - Keith Chong
 *******************************************************************************/

package org.eclipse.wst.ws.internal.parser.wsil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.codec.binary.Base64;
import org.apache.wsil.Abstract;
import org.apache.wsil.Description;
import org.apache.wsil.Inspection;
import org.apache.wsil.Link;
import org.apache.wsil.Service;
import org.apache.wsil.WSILConstants;
import org.apache.wsil.WSILDocument;
import org.apache.wsil.WSILException;
import org.apache.wsil.extension.ExtensionElement;
import org.apache.wsil.extension.uddi.ServiceDescription;
import org.apache.wsil.extension.uddi.UDDIConstants;
import org.apache.wsil.extension.wsdl.WSDLConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.ws.internal.parser.disco.DISCOContractReference;
import org.eclipse.wst.ws.internal.parser.disco.DISCOParser;
import org.eclipse.wst.ws.internal.parser.disco.DISCOReference;
import org.eclipse.wst.wsdl.WSDLPlugin;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class WebServicesParser {
    public static final int PARSE_NONE = 0;
    public static final int PARSE_WSIL = 1 << 0;
    public static final int PARSE_WSDL = 1 << 1;
    public static final int PARSE_LINKS = 1 << 2;
    public static final int PARSE_DISCO = 1 << 3;

    private String uri_;
    private Hashtable uriToEntityTable_;

    private String httpBasicAuthUsername_;
    private String httpBasicAuthPassword_;

    public WebServicesParser() {
        this(null);
    }

    public WebServicesParser(String uri) {
        uri_ = uri;
        uriToEntityTable_ = new Hashtable();
        httpBasicAuthUsername_ = null;
        httpBasicAuthPassword_ = null;
    }

    public String getURI() {
        return uri_;
    }

    public void setURI(String uri) {
        uri_ = uri;
    }

    public WebServiceEntity getWebServiceEntityByURI(String uri) {
        if (uri != null)
            return (WebServiceEntity) uriToEntityTable_.get(uri);
        else
            return null;
    }

    /**
     * 
     * @param wsilURI
     * @return
     * @deprecated replaced with getWSILDocumentVerbose(String, String)
     */
    public WSILDocument getWSILDocument(String wsilURI) {
        try {
            return getWSILDocumentVerbose(wsilURI, "UTF-8");
        } catch (Exception t) {
        }
        return null;
    }

    /**
     * 
     * @param wsilURI
     * @return
     * @throws MalformedURLException
     * @throws IOException
     * @throws WWWAuthenticationException
     * @throws WSILException
     * @deprecated replaced with getWSILDocumentVerbose(String, String)
     */
    public WSILDocument getWSILDocumentVerbose(String wsilURI)
            throws MalformedURLException, IOException, WWWAuthenticationException, WSILException {
        return getWSILDocumentVerbose(wsilURI, "UTF-8");
    }

    public WSILDocument getWSILDocumentVerbose(String wsilURI, String byteEncoding)
            throws MalformedURLException, IOException, WWWAuthenticationException, WSILException {
        WebServiceEntity wsEntity = getWebServiceEntityByURI(wsilURI);

        if (wsEntity == null) {
            wsEntity = new WebServiceEntity();
            wsEntity.setURI(wsilURI);
            uriToEntityTable_.put(wsilURI, wsEntity);
        }

        WSILDocument wsilDocument = (WSILDocument) wsEntity.getModel();

        if (wsilDocument == null) {
            // For some reason WSDL4J is not reading the content type properly for platform resources.  Therefore, we will get
            // the stream directly from Eclipse if we find a platform protocol specified in the URL.
            if (wsilURI.startsWith("platform:/resource")) {
                String path = wsilURI.substring(18);
                IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);

                if (resource instanceof IFile) {
                    try {
                        IFile file = (IFile) resource;
                        InputStream stream = file.getContents();
                        InputStreamReader reader = new InputStreamReader(stream, file.getCharset());

                        wsilDocument = WSILDocument.newInstance();
                        wsilDocument.read(reader);
                    } catch (CoreException exc) {
                    }
                }
            } else {
                // TODO the following 3 lines of code should probably be removed, since
                // the WSDL4J parser does not need a byte stream.
                byte[] b = getInputStreamAsByteArray(wsilURI);
                wsEntity.setBytes(b);
                setHTTPSettings(wsEntity);

                // This parser only checks the header of HTML for a particular encoding.
                // It doesn't check the encoding for general XML documents like WSDL and WSIL.
                // This causing this parser to alway use UTF-8 as the encoding.  Therefore,
                // since we can not trust the encoding specified we will not use it.  Instead,
                // we will just let the WSIL parser figure out what encoding to use.

                //InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(b), byteEncoding );
                wsilDocument = WSILDocument.newInstance();
                wsilDocument.read(wsilURI);
            }

            wsEntity.setType(WebServiceEntity.TYPE_WSIL);
            wsEntity.setModel(wsilDocument);
        }
        return wsilDocument;
    }

    public Definition getWSDLDefinition(String wsdlURI) {
        try {
            return getWSDLDefinitionVerbose(wsdlURI);
        } catch (Exception t) {
        }
        return null;
    }

    public Definition getWSDLDefinitionVerbose(String wsdlURI)
            throws MalformedURLException, IOException, WWWAuthenticationException, WSDLException {
        WebServiceEntity wsEntity = getWebServiceEntityByURI(wsdlURI);
        if (wsEntity == null) {
            wsEntity = new WebServiceEntity();
            wsEntity.setURI(wsdlURI);
            uriToEntityTable_.put(wsdlURI, wsEntity);
        }
        Definition definition = (Definition) wsEntity.getModel();
        if (definition == null) {
            byte[] b = getInputStreamAsByteArray(wsdlURI);
            wsEntity.setBytes(b);
            setHTTPSettings(wsEntity);
            ByteArrayInputStream bais = new ByteArrayInputStream(b);
            WSDLFactory factory = WSDLPlugin.INSTANCE.createWSDL4JFactory();
            WSDLReader wsdlReader = factory.newWSDLReader();
            definition = wsdlReader.readWSDL(wsdlURI.replace('\\', '/'), new InputSource(bais));
            wsEntity.setType(WebServiceEntity.TYPE_WSDL);
            wsEntity.setModel(definition);
        }
        return definition;
    }

    public void parse() throws MalformedURLException, IOException, ParserConfigurationException, SAXException,
            WWWAuthenticationException {
        parseURL(PARSE_WSIL | PARSE_WSDL | PARSE_LINKS | PARSE_DISCO);
    }

    public void parse(int parseOption) throws MalformedURLException, IOException, ParserConfigurationException,
            SAXException, WWWAuthenticationException {
        parseURL(parseOption);
    }

    private void parseURL(int parseOption) throws MalformedURLException, IOException, ParserConfigurationException,
            SAXException, WWWAuthenticationException {
        WebServiceEntity wsEntity = new WebServiceEntity();

        // This variable makes this object a little more thread safe than it was
        // before, although this object is not completely thread safe.  The scenario
        // that we are trying to avoid is where one call to this method gets blocked
        // at the getInputStreamAsByteArray call.  Then a second call to the method
        // is made that changes the uri_ global variable.  When the first call
        // completes it would use uri_ value from the second invocation instead
        // of the value from the first.  Storing the uri_ into this variable helps 
        // avoid this bad scenario.
        String theUri = uri_;

        wsEntity.setURI(theUri);
        byte[] b = getInputStreamAsByteArray(theUri);
        wsEntity.setBytes(b);
        setHTTPSettings(wsEntity);
        uriToEntityTable_.put(theUri, wsEntity);
        // parse uri_ as a HTML document
        HTMLHeadHandler headHandler = new HTMLHeadHandler(theUri);
        byte[] head = headHandler.harvestHeadTags(b);
        String byteEncoding = headHandler.getByteEncoding();
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(false);
        factory.setValidating(false);
        SAXParser parser = factory.newSAXParser();
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(head);
            InputStreamReader isr = new InputStreamReader(bais, byteEncoding);
            InputSource is = new InputSource(isr);
            parser.parse(is, headHandler);
        } catch (Exception t) {
        }
        String[] wsilURIs = headHandler.getWsils();
        String[] discoURIs = headHandler.getDiscos();
        // true if uri_ is a HTML document
        if (wsilURIs.length > 0 || discoURIs.length > 0) {
            wsEntity.setType(WebServiceEntity.TYPE_HTML);
            for (int i = 0; i < wsilURIs.length; i++) {
                String absoluteURI = convertToAbsoluteURI(theUri, wsilURIs[i]);
                WebServiceEntity wsilEntity = new WebServiceEntity();
                wsilEntity.setType(WebServiceEntity.TYPE_WSIL);
                wsilEntity.setURI(absoluteURI);
                associate(wsEntity, wsilEntity);
                uriToEntityTable_.put(absoluteURI, wsilEntity);
                if ((parseOption | PARSE_WSIL) == parseOption) {
                    try {
                        parseWSIL(absoluteURI, parseOption, byteEncoding);
                    } catch (Exception t) {
                    }
                }
            }
            for (int i = 0; i < discoURIs.length; i++) {
                WebServiceEntity discoEntity = new WebServiceEntity();
                discoEntity.setType(WebServiceEntity.TYPE_DISCO);
                discoEntity.setURI(discoURIs[i]);
                associate(wsEntity, discoEntity);
                uriToEntityTable_.put(discoURIs[i], discoEntity);
                if ((parseOption | PARSE_DISCO) == parseOption) {
                    try {
                        parseDISCO(discoURIs[i], parseOption);
                    } catch (Exception t) {
                    }
                }
            }
        }
        // false if uri_ is not a HTML document
        // then parse uri_ as a WSIL document
        else {
            try {
                parseWSIL(theUri, parseOption, byteEncoding);
                // no exception thrown if uri_ is a WSIL document
                wsEntity.setType(WebServiceEntity.TYPE_WSIL);
            } catch (Exception t) {
                // exception thrown if uri_ is not a WSIL document
                // then parse uri_ as a DISCO document.
                try {
                    parseDISCO(theUri, parseOption);
                    // no exception thrown if uri_ is a DISCO document
                    wsEntity.setType(WebServiceEntity.TYPE_DISCO);
                } catch (Exception t2) {
                    // exception thrown if uri_ is not a DISCO document
                    // then parse uri_ as a WSDL document
                    try {
                        parseWSDL(theUri);
                        // no exception thrown if uri_ is a WSDL document
                        wsEntity.setType(WebServiceEntity.TYPE_WSDL);
                    } catch (Exception t3) {
                        // exception thrown if uri_ is not a WSDL document
                        // then do nothing
                    }
                }
            }
        }
    }

    private void parseWSIL(String wsilURI, int parseOption, String byteEncoding)
            throws WSILException, MalformedURLException, IOException, WSDLException, WWWAuthenticationException {
        WebServiceEntity wsilEntity = getWebServiceEntityByURI(wsilURI);
        WSILDocument wsilDoc = (WSILDocument) wsilEntity.getModel();
        if (wsilDoc != null) {
            // Prevent infinite loops from occurring when a WSIL cycles occur.
            return;
        }
        wsilDoc = getWSILDocumentVerbose(wsilURI, byteEncoding);
        Inspection inspection = wsilDoc.getInspection();
        Service[] services = inspection.getServices();
        for (int i = 0; i < services.length; i++) {
            Description[] descs = services[i].getDescriptions();
            // Set the documentation to the <service> element's first abstract.
            String documentation = null;
            Abstract[] abstracts = services[i].getAbstracts();
            if (abstracts != null && abstracts.length > 0)
                documentation = abstracts[0].getText();
            for (int j = 0; j < descs.length; j++) {
                String referencedNS = descs[j].getReferencedNamespace();
                // If a <description> element contains an abstract, use it to override the service documentation.         
                abstracts = descs[j].getAbstracts();
                if (abstracts != null && abstracts.length > 0)
                    documentation = abstracts[0].getText();
                if (WSDLConstants.NS_URI_WSDL.equals(referencedNS)) {
                    String location = descs[j].getLocation();
                    if (location != null && location.length() > 0) {
                        String absoluteURI = convertToAbsoluteURI(wsilURI, location);
                        WebServiceEntity wsdlEntity = new WebServiceEntity();
                        wsdlEntity.setType(WebServiceEntity.TYPE_WSDL);
                        wsdlEntity.setURI(absoluteURI);
                        wsdlEntity.setDocumentation(documentation);
                        associate(wsilEntity, wsdlEntity);
                        uriToEntityTable_.put(absoluteURI, wsdlEntity);
                        if ((parseOption | PARSE_WSDL) == parseOption)
                            parseWSDL(absoluteURI);
                    }
                } else if (UDDIConstants.NS_URI_UDDI_V2.equals(referencedNS)) {
                    ExtensionElement ee = descs[j].getExtensionElement();
                    if (ee instanceof ServiceDescription) {
                        ServiceDescription sd = (ServiceDescription) ee;
                        String inquiryURL = sd.getLocation();
                        String serviceKey = sd.getServiceKey().getText();
                        WebServiceEntity uddiServiceEntity = new WebServiceEntity();
                        uddiServiceEntity.setType(WebServiceEntity.TYPE_UDDI_SERVICE);
                        String uddiServiceKeyURI = UDDIURIHelper.getServiceKeyURI(serviceKey, inquiryURL);
                        uddiServiceEntity.setURI(uddiServiceKeyURI);
                        uddiServiceEntity.setDocumentation(documentation);
                        associate(wsilEntity, uddiServiceEntity);
                        uriToEntityTable_.put(uddiServiceKeyURI, uddiServiceEntity);
                        // TODO: parse WSDL if necessary...
                    }
                }
            }
        }
        Link[] links = inspection.getLinks();
        for (int i = 0; i < links.length; i++) {
            if (WSILConstants.NS_URI_WSIL.equals(links[i].getReferencedNamespace())) {
                String documentation = null;
                Abstract[] abstracts = links[i].getAbstracts();
                if (abstracts != null && abstracts.length > 0)
                    documentation = abstracts[0].getText();
                String linkLocation = links[i].getLocation();
                String absoluteURI = convertToAbsoluteURI(wsilURI, linkLocation);
                // Prevent cycles.
                WebServiceEntity wsilLinkEntity = getWebServiceEntityByURI(absoluteURI);
                if (wsilLinkEntity == null) {
                    wsilLinkEntity = new WebServiceEntity();
                    wsilLinkEntity.setType(WebServiceEntity.TYPE_WSIL);
                    wsilLinkEntity.setURI(absoluteURI);
                    wsilLinkEntity.setDocumentation(documentation);
                    uriToEntityTable_.put(absoluteURI, wsilLinkEntity);
                    if ((parseOption | PARSE_LINKS) == parseOption)
                        parseWSIL(absoluteURI, parseOption, byteEncoding);
                }
                associate(wsilEntity, wsilLinkEntity);
            }
        }
    }

    private void parseDISCO(String discoURI, int parseOption)
            throws MalformedURLException, WWWAuthenticationException, Exception {
        WebServiceEntity discoEntity = getWebServiceEntityByURI(discoURI);
        byte[] b = getInputStreamAsByteArray(discoURI);
        discoEntity.setBytes(b);
        setHTTPSettings(discoEntity);
        ByteArrayInputStream bais = new ByteArrayInputStream(b);
        DISCOParser parser = new DISCOParser();
        DISCOReference[] references = parser.parse(discoURI, new InputSource(bais));
        if (references != null && references.length > 0) {
            for (int i = 0; i < references.length; i++) {
                if (references[i] instanceof DISCOContractReference) {
                    // contractRef
                    DISCOContractReference reference = (DISCOContractReference) references[i];
                    String ref = reference.getRef();
                    String docRef = reference.getDocRef();
                    WebServiceEntity wsdlEntity = new WebServiceEntity();
                    wsdlEntity.setType(WebServiceEntity.TYPE_WSDL);
                    wsdlEntity.setURI(ref);
                    wsdlEntity.setDocumentation(docRef);
                    associate(discoEntity, wsdlEntity);
                    uriToEntityTable_.put(ref, wsdlEntity);
                    if ((parseOption | PARSE_WSDL) == parseOption)
                        parseWSDL(ref);
                } else {
                    // discoveryRef
                    String ref = references[i].getRef();
                    // Prevent cycles.
                    WebServiceEntity discoLinkEntity = getWebServiceEntityByURI(ref);
                    if (discoLinkEntity == null) {
                        discoLinkEntity = new WebServiceEntity();
                        discoLinkEntity.setType(WebServiceEntity.TYPE_DISCO);
                        discoLinkEntity.setURI(ref);
                        uriToEntityTable_.put(ref, discoLinkEntity);
                        if ((parseOption | PARSE_LINKS) == parseOption)
                            parseDISCO(ref, parseOption);
                    }
                    associate(discoEntity, discoLinkEntity);
                }
            }
        }
    }

    private Definition parseWSDL(String wsdlURI)
            throws WSDLException, MalformedURLException, IOException, WWWAuthenticationException {
        return getWSDLDefinitionVerbose(wsdlURI);
    }

    private byte[] getInputStreamAsByteArray(String uriString)
            throws MalformedURLException, IOException, WWWAuthenticationException {
        // Try to get a cached copy of the byte[]
        WebServiceEntity wsEntity = getWebServiceEntityByURI(uriString);
        if (wsEntity != null) {
            byte[] bytes = wsEntity.getBytes();
            if (bytes != null)
                return bytes;
        }
        // Get the byte[] by opening a stream to the URI
        URL url = createURL(uriString);
        URLConnection conn = url.openConnection();
        // proxy server setting
        String proxyUserName = System.getProperty("http.proxyUserName");
        String proxyPassword = System.getProperty("http.proxyPassword");
        if (proxyUserName != null && proxyPassword != null) {
            StringBuffer userNamePassword = new StringBuffer(proxyUserName);
            userNamePassword.append(':').append(proxyPassword);
            Base64 encoder = new Base64();
            String encoding = new String(encoder.encode(userNamePassword.toString().getBytes()));
            userNamePassword.setLength(0);
            userNamePassword.append("Basic ").append(encoding);
            conn.setRequestProperty("Proxy-authorization", userNamePassword.toString());
        }
        // HTTP basic authentication setting
        if (httpBasicAuthUsername_ != null && httpBasicAuthPassword_ != null) {
            StringBuffer sb = new StringBuffer(httpBasicAuthUsername_);
            sb.append(':').append(httpBasicAuthPassword_);
            Base64 encoder = new Base64();
            String encoding = new String(encoder.encode(sb.toString().getBytes()));
            sb.setLength(0);
            sb.append("Basic ").append(encoding);
            conn.setRequestProperty("Authorization", sb.toString());
        }
        InputStream is = null;
        try {
            is = conn.getInputStream();
            String wwwAuthMsg = conn.getHeaderField("WWW-Authenticate");
            if (wwwAuthMsg != null)
                throw new WWWAuthenticationException(new IOException(), wwwAuthMsg, uriString);
        } catch (IOException ioe) {
            String wwwAuthMsg = conn.getHeaderField("WWW-Authenticate");
            if (wwwAuthMsg != null)
                throw new WWWAuthenticationException(ioe, wwwAuthMsg, uriString);
            else
                throw ioe;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int byteRead = is.read(b);
        while (byteRead != -1) {
            baos.write(b, 0, byteRead);
            byteRead = is.read(b);
        }
        is.close();
        return baos.toByteArray();
    }

    protected URL createURL(String url) throws MalformedURLException {
        return new URL(url);
    }

    private void associate(WebServiceEntity parent, WebServiceEntity child) {
        parent.addChild(child);
        child.setParent(parent);
    }

    private String convertToAbsoluteURI(String baseURI, String refURI) {
        if (refURI != null && refURI.indexOf(":") < 0) {
            StringBuffer absoluteURI = new StringBuffer(
                    baseURI.substring(0, Math.max(baseURI.lastIndexOf('\\'), baseURI.lastIndexOf('/') + 1)));
            absoluteURI.append(refURI);
            return absoluteURI.toString();
        }
        return refURI;
    }

    private void setHTTPSettings(WebServiceEntity entity) {
        if (httpBasicAuthUsername_ != null && httpBasicAuthPassword_ != null) {
            entity.setHTTPUsername(httpBasicAuthUsername_);
            entity.setHTTPPassword(httpBasicAuthPassword_);
        }
    }

    public String getHTTPBasicAuthUsername() {
        return httpBasicAuthUsername_;
    }

    public void setHTTPBasicAuthUsername(String username) {
        httpBasicAuthUsername_ = username;
    }

    public String getHTTPBasicAuthPassword() {
        return httpBasicAuthPassword_;
    }

    public void setHTTPBasicAuthPassword(String password) {
        httpBasicAuthPassword_ = password;
    }
}