Package org.fcrepo.server.utilities

Source Code of org.fcrepo.server.utilities.RuntimeWSDL

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.utilities;

import java.io.File;
import java.io.IOException;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* Utility for combining WSDL and XSD into a single file, with a specific
* service endpoint.
*
* @author Chris Wilper
*/
public class RuntimeWSDL {

    /** The final WSDL document. */
    private Document _wsdlDoc;

    /**
     * Instantiate from the given files and service endpoint URL.
     */
    public RuntimeWSDL(File schemaFile, File sourceWSDL, String endpoint)
            throws IOException {

        try {

            // init dom parser and parse input
            DocumentBuilderFactory factory =
                    DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document xsdDoc = builder.parse(schemaFile);
            _wsdlDoc = builder.parse(sourceWSDL);

            // put schema into the wsdl types section
            Element typesElement = getTopElement("types");
            removeChildren(typesElement);
            Node xsdNode =
                    _wsdlDoc.importNode(xsdDoc.getDocumentElement(), true); // deep copy
            typesElement.appendChild(xsdNode);

            // set the endpoint
            // - requires an existing service element with a name attribute
            // - requires at least one port element under the service element
            // - removes extra ports if more than one exist under service
            // - sets the port name to service[@name] plus "-$scheme-Port",
            //   where $scheme the uppercase URI scheme of the endpoint
            // - sets the address location to given endpoint URL
            Element serviceElement = getTopElement("service");
            String serviceName = serviceElement.getAttributeNS(null, "name");
            if (serviceName == null) {
                throw new IOException("WSDL missing required attribute of "
                        + "service element: name");
            }

            NodeList ports = serviceElement.getElementsByTagNameNS("*", "port");

            while (ports.getLength() > 1) {
                serviceElement.removeChild(ports.item(0));
            }
            if (ports.getLength() == 0) {
                throw new IOException("WSDL missing required element: port");
            }
            Element port = (Element) ports.item(0);

            int i = endpoint.indexOf(":");
            String schemePart = "";
            if (i != -1) {
                schemePart = "-" + endpoint.substring(0, i).toUpperCase();
            }
            port.setAttribute("name", serviceName + schemePart + "-Port");

            Element address =
                    (Element) port.getElementsByTagNameNS("*", "address")
                            .item(0);
            if (address != null) {
                address.setAttribute("location", endpoint);
            } else {
                throw new IOException("WSDL missing required element: address");
            }

        } catch (Exception e) {
            if (e instanceof IOException) {
                throw (IOException) e;
            } else {
                throw new IOException("Error getting RuntimeWSDL", e);
            }
        }
    }

    private Element getTopElement(String name) throws IOException {
        Element element =
                (Element) _wsdlDoc.getDocumentElement()
                        .getElementsByTagNameNS("*", name).item(0);
        if (element != null) {
            return element;
        } else {
            throw new IOException("WSDL missing required element: " + name);
        }
    }

    private static final void removeChildren(Element element) {
        Node firstChild = element.getFirstChild();
        while (firstChild != null) {
            element.removeChild(firstChild);
            firstChild = element.getFirstChild();
        }
    }

    /**
     * Serialize the final WSDL document to the given writer.
     */
    public void serialize(Writer out) throws IOException {

        OutputFormat fmt = new OutputFormat("XML", "UTF-8", true);
        fmt.setIndent(2);
        fmt.setLineWidth(80);
        fmt.setPreserveSpace(false);
        fmt.setOmitXMLDeclaration(false);
        fmt.setOmitDocumentType(true);

        XMLSerializer ser = new XMLSerializer(out, fmt);

        ser.serialize(_wsdlDoc);
    }

    /**
     * Command-line test. Usage: java RuntimeWSDL schemaFile sourceWSDL endpoint
     */
    public static void main(String[] args) throws Exception {
        java.io.PrintWriter out = new java.io.PrintWriter(System.out);
        new RuntimeWSDL(new File(args[0]), new File(args[1]), args[2])
                .serialize(out);
        out.flush();
    }

}
TOP

Related Classes of org.fcrepo.server.utilities.RuntimeWSDL

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.