view src/org/ssdt_ohio/tools/ant/WsdlSetup.java @ 2:09f9f3d5c507

CM-127: Move wsdlsetup and wsd2html.xsl from Tools
author smith@nwoca.org
date Tue, 07 Jun 2011 18:06:07 -0400
parents
children
line wrap: on
line source
/* Copyright 2003 Ohio Department of Education, Office of Information Technology,
 *      25 South Front St, Columbus, Ohio 43215, U.S.A., All Rights Reserved.
 */
package org.ssdt_ohio.tools.ant;

import java.io.File;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

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

import java.util.regex.Pattern;

/** Simple ant task for maniuplating WSDL settings.
 *
 *
 * @author smith
 * @since 2007-8-1
 */
public class WsdlSetup
        extends Task {

    private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
    private static final String OECNRPC_NS = "http://xml.ssdt.nwoca.org/OECN-RPC/10";
    private final List locations = new ArrayList(); /* Store locations */

    private String file;
    private String destfile;
    private String typesFile;
    private String typesPattern = ".*Fault$";
    private boolean elementFormDefaultQualified = true;

    public void execute() {
        if (file == null) {
            throw new BuildException("must specify 'file' as input file");
        }

        if (destfile == null) {
            throw new BuildException("must specify 'destfile' as output file");
        }

        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);

            Document wsdl = dbf.newDocumentBuilder().parse(new File(getFile()));
            NodeList imports = wsdl.getElementsByTagNameNS(SCHEMA_NS, "import");

            for (int i = 0; i < imports.getLength(); i++) {
                replaceLocations((Element) imports.item(i));
            }

            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();
            DOMSource source = new DOMSource(wsdl);
            StreamResult result = new StreamResult(new File(getDestfile()));
            transformer.transform(source, result);

            if (typesFile != null) {
                generateTypesSchema(wsdl);
            }
        } catch (javax.xml.parsers.ParserConfigurationException e) {
            throw new BuildException(e);
        } catch (org.xml.sax.SAXException e) {
            throw new BuildException(e);
        } catch (java.io.IOException e) {
            throw new BuildException(e);
        } catch (javax.xml.transform.TransformerException e) {
            throw new BuildException(e);
        }
    }

    private void replaceLocations(Element imp) {
        String ns = imp.getAttribute("namespace");

        for (Iterator it = locations.iterator(); it.hasNext();) {
            SchemaLocation loc = (SchemaLocation) it.next();

            if (ns.equals(loc.getNamespace())) {
                imp.setAttribute("schemaLocation", loc.getLocation());
            }
        }
    }

    private void generateTypesSchema(Document wsdl)
            throws BuildException {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);

            Document schema = dbf.newDocumentBuilder().newDocument();
            Element root = (Element) wsdl.getElementsByTagNameNS(SCHEMA_NS,
                                                                 "schema").item(0);
            String targetNamespace = root.getAttribute("targetNamespace");

            schema.appendChild(schema.importNode(root, true));
            root = schema.getDocumentElement();
            root.setAttribute("xmlns:xsd", SCHEMA_NS);
            if (isElementFormDefaultQualified()) {
                root.setAttribute("elementFormDefault", "qualified");
            }
            root.setAttribute("xmlns", targetNamespace);
            root.setAttribute("xmlns:oecnrpc", OECNRPC_NS);

            for (Iterator it = locations.iterator(); it.hasNext();) {
                SchemaLocation loc = (SchemaLocation) it.next();

                if (loc.getPrefix() != null) {
                    root.setAttribute("xmlns:" + loc.getPrefix(), loc.getNamespace());
                }
            }

            // Remove everything except the included types.
            boolean done = false;

            Pattern typesPat = Pattern.compile(getTypesPattern());

            while (!done) {
                done = true;

                NodeList children = root.getChildNodes();

                for (int i = 0; i < children.getLength(); i++) {
                    if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
                        Element e = (Element) children.item(i);

                        if (!e.getLocalName().equals("import") && !typesPat.matcher(e.
                                getAttribute("name")).matches()) {
                            root.removeChild(e);
                            done = false;
                        }
                    }
                }
            }
            TransformerFactory tFactory = TransformerFactory.newInstance();
            Transformer transformer = tFactory.newTransformer();

            DOMSource source = new DOMSource(schema);
            StreamResult result = new StreamResult(new File(getTypesFile()));
            transformer.transform(source, result);
        } catch (Exception e) {
            throw new BuildException(e);
        }
    }
  
    public SchemaLocation createSchemaLocation() {
        SchemaLocation loc = new SchemaLocation();
        locations.add(loc);

        return loc;
    }

    /**
     * Getter for property file.
     * @return Value of property file.
     */
    public java.lang.String getFile() {
        return file;
    }

    /**
     * Setter for property file.
     * @param file New value of property file.
     */
    public void setFile(java.lang.String file) {
        this.file = file;
    }

    /**
     * Getter for property destfile.
     * @return Value of property destfile.
     */
    public java.lang.String getDestfile() {
        return destfile;
    }

    /**
     * Setter for property destfile.
     * @param destfile New value of property destfile.
     */
    public void setDestfile(java.lang.String destfile) {
        this.destfile = destfile;
    }

    /**
     * Getter for property typesFile.
     * @return Value of property typesFile.
     */
    public java.lang.String getTypesFile() {
        return typesFile;
    }

    /**
     * Setter for property typesFile.
     * @param typesFile New value of property typesFile.
     */
    public void setTypesFile(java.lang.String typesFile) {
        this.typesFile = typesFile;
    }

    /**
     * @return the elementFormDefaultQualified
     */
    public boolean isElementFormDefaultQualified() {
        return elementFormDefaultQualified;
    }

    /**
     * @param elementFormDefaultQualified the elementFormDefaultQualified to set
     */
    public void setElementFormDefaultQualified(boolean elementFormDefaultQualified) {
        this.elementFormDefaultQualified = elementFormDefaultQualified;
    }

    /** A nested 'schemaLocation' object. */
    public class SchemaLocation {

        private String namespace;
        private String location;
        private String prefix;

        public SchemaLocation() {
        }

        public java.lang.String getNamespace() {
            return namespace;
        }

        public void setNamespace(java.lang.String namespace) {
            this.namespace = namespace;
        }

        public java.lang.String getLocation() {
            return location;
        }

        public void setLocation(java.lang.String location) {
            this.location = location;
        }

        public String getPrefix() {
            return prefix;
        }

        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    }

    public String getTypesPattern() {
        return typesPattern;
    }

    public void setTypesPattern(String typesPattern) {
        this.typesPattern = typesPattern;
    }
}