Package org.objectweb.celtix.tools.processors.wsdl2.validators

Source Code of org.objectweb.celtix.tools.processors.wsdl2.validators.SchemaWSDLValidator

package org.objectweb.celtix.tools.processors.wsdl2.validators;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
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.Vector;

import javax.wsdl.WSDLException;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;

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

import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.sun.org.apache.xerces.internal.parsers.DOMParser;
import com.sun.org.apache.xerces.internal.parsers.XMLGrammarPreparser;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
import com.sun.org.apache.xerces.internal.xni.grammars.XSGrammar;
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
import com.sun.org.apache.xerces.internal.xs.XSModel;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

import org.objectweb.celtix.tools.common.ToolException;
import org.objectweb.celtix.tools.common.WSDLConstants;
import org.objectweb.celtix.tools.utils.LineNumDOMParser;
import org.objectweb.celtix.tools.utils.URLFactory;
import org.objectweb.celtix.tools.utils.WSDLExtensionRegister;

public class SchemaWSDLValidator extends AbstractValidator {

    protected String[] defaultSchemas;
    protected String schemaLocation = "./";

    private DOMParser parser;
    private XMLGrammarPreparser preparser;

    private List<XSModel> xsmodelList = new Vector<XSModel>();

    private String wsdlsrc;
    private String[] xsds;
    private boolean isdeep;

    private Document schemaValidatedDoc;
    private Map<QName, List> msgPartsMap = new HashMap<QName, List>();
    private Map<QName, Map> portTypes = new HashMap<QName, Map>();
    private Map<QName, QName> bindingMap = new HashMap<QName, QName>();

    public SchemaWSDLValidator(String schemaDir) throws ToolException {
        super(schemaDir);
        schemaLocation = schemaDir;
        defaultSchemas = getDefaultSchemas();
        init();
    }

    public SchemaWSDLValidator(String schemaDir, String wsdl, String[] schemas, boolean deep) {
        super(schemaDir);
        schemaLocation = schemaDir;
        defaultSchemas = getDefaultSchemas();
        init();
        wsdlsrc = wsdl;
        xsds = schemas;
        isdeep = deep;
    }

    public boolean isValid() {
        return validate(wsdlsrc, xsds, isdeep);
    }

    public boolean validate(String wsdlsource, String[] schemas, boolean deep) throws ToolException {
        String systemId = null;
        try {
            systemId = getWsdlUrl(wsdlsource);
        } catch (IOException ioe) {
            throw new ToolException(ioe);
        }

        return validate(new InputSource(systemId), schemas, deep);

    }

    private boolean validate(InputSource wsdlsource, String[] schemas, boolean deep) throws ToolException {
        boolean isValid = false;
        try {
            schemas = addSchemas(defaultSchemas, schemas);
            setExternalSchemaLocations(schemas);
            StackTraceErrorHandler handler = setErrorHandler();
            schemaValidatedDoc = doValidation(wsdlsource, deep);
            //
            if (!handler.isValid()) {
                ToolException ex = new ToolException(handler.getErrorMessages());
                throw ex;
            }

            WSDLFactory wsdlFactory;
            try {
                wsdlFactory = WSDLFactory.newInstance();
                WSDLReader reader = wsdlFactory.newWSDLReader();
                reader.setFeature("javax.wsdl.verbose", false);
                WSDLExtensionRegister register = new WSDLExtensionRegister(wsdlFactory , reader);
                register.registerExtenstions();
                def = reader.readWSDL(wsdlsource.getSystemId());
            } catch (WSDLException e) {
                throw new ToolException("Can not create wsdl definition for " + wsdlsource.getSystemId());
            }
           
            WSDLElementReferenceValidator wsdlRefValiadtor = new WSDLElementReferenceValidator(def, this);
            isValid = wsdlRefValiadtor.isValid();
           
            if (!isValid) {
                throw new ToolException(this.getErrorMessage());
            }
           
            isValid = true;

        } catch (IOException ioe) {
            throw new ToolException("Can not get the wsdl " + wsdlsource.getSystemId() , ioe);
        } catch (SAXException saxEx) {
            throw new ToolException(saxEx);

        }
        return isValid;
    }

    public Document validate(InputStream wsdlsource, String[] schemas) throws Exception {
        schemas = addSchemas(defaultSchemas, schemas);
        setExternalSchemaLocations(schemas);
        StackTraceErrorHandler handler = setErrorHandler();
        Document doc = doValidation(new InputSource(wsdlsource), false);

        if (!handler.isValid()) {
            throw new SAXException(handler.getErrorMessages());
        }
        return doc;
    }

    public Document validate(String wsdlsource, String[] schemas) throws ToolException {
        schemas = addSchemas(defaultSchemas, schemas);
        Document doc = null;
        try {
            setExternalSchemaLocations(schemas);
            // StackTraceErrorHandler handler = setErrorHandler();
            setErrorHandler();
            doc = doValidation(new InputSource(getWsdlUrl(wsdlsource)), false);
            /*
             * if (!handler.isValid()) { ToolException ex = new
             * ToolException(handler.getErrorMessages()); throw ex; }
             */
        } catch (Exception e) {
            ToolException ex = new ToolException(e);
            throw ex;
        }
        return doc;
    }

    void setErrorHandler(StackTraceErrorHandler handler) {
        parser.setErrorHandler(handler);

        preparser.setErrorHandler(handler);
    }

    private void init() throws ToolException {
        try {

            parser = new LineNumDOMParser();
            preparser = new XMLGrammarPreparser();
            parser.setFeature("http://xml.org/sax/features/validation", true);
            parser.setFeature("http://apache.org/xml/features/validation/schema", true);
            parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
            parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

            preparser.registerPreparser(XMLGrammarDescription.XML_SCHEMA, null);
            preparser.setFeature("http://xml.org/sax/features/namespaces", true);
            preparser.setFeature("http://xml.org/sax/features/validation", true);
            preparser.setFeature("http://apache.org/xml/features/validation/schema", true);
            preparser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);

            EntityResolver eresolver = new EntityResolver() {
                public InputSource resolveEntity(String publicID, String systemID) throws SAXException,
                    IOException {

                    String url = resolveUrl(systemID);
                    if (url == null) {
                        String msg = "Can't resolve entity from publicID=" + publicID + ", systemID="
                                     + systemID;

                        throw new IOException(msg);
                    }
                    return new InputSource(url);
                }
            };

            parser.setEntityResolver(eresolver);

            SchemaEntityResolver xmlResolver = new SchemaEntityResolver();
            preparser.setEntityResolver(xmlResolver);
        } catch (SAXException sax) {
            Throwable embedded = sax.getException();
            if (embedded == null) {
                embedded = sax;
            }
            throw new ToolException(sax.getMessage());
        }
    }

    private String[] addSchemas(String[] defaults, String[] schemas) {
        if (schemas == null || schemas.length == 0) {
            return defaultSchemas;
        }
        String[] ss = new String[schemas.length + defaults.length];
        System.arraycopy(defaults, 0, ss, 0, defaults.length);
        System.arraycopy(schemas, 0, ss, defaults.length, schemas.length);
        return ss;
    }

    private Document doValidation(InputSource wsdlsource, boolean deep) throws IOException, SAXException,
        ToolException {

        byte[] bytes = getBytes(wsdlsource);
        parser.parse(copyInputSource(wsdlsource, bytes));
        Document doc = parser.getDocument();

        String base = wsdlsource.getSystemId();
        if (doc == null) {
            return null;
        }

        if (deep) {
            NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS(WSDLConstants.NS_WSDL, "import");
            for (int i = 0; i < nodes.getLength(); i++) {
                Element el = (Element)nodes.item(i);
                String ns = el.getAttribute("namespace");
                String loc = el.getAttribute("location");

                if (!"".equals(ns) && !"".equals(loc)) {

                    SchemaWSDLValidator validator = new SchemaWSDLValidator(schemaLocation);
                    validator.setErrorHandler(getErrorHandler());

                    validator.validate(new InputSource(getWsdlUrl(base, loc)), null, true);

                    if (!getErrorHandler().isValid()) {
                        throw new SAXException(getErrorHandler().getErrorMessages());
                    }
                    return doc;

                }
            }
        }
        StackTraceErrorHandler handler = getErrorHandler();
        if (handler.isValid()) {
            doSchemaValidation(wsdlsource, bytes, doc, handler);
        }
        return doc;
    }

    private byte[] getBytes(InputSource source) throws IOException {
        if (source.getByteStream() != null) {
            int length = source.getByteStream().available();
            byte[] bytes = new byte[length];
            source.getByteStream().read(bytes);
            return bytes;
        }
        return null;
    }

    private void doSchemaValidation(InputSource wsdlsource, byte[] bytes, Document doc,
                                    StackTraceErrorHandler handler) throws IOException, SAXException {
        if (isSchemaDocument(doc)) {
            XSGrammar xsGrammer = (XSGrammar)preparser.preparseGrammar(XMLGrammarDescription.XML_SCHEMA,
                                                                       copyInputSourceXML(wsdlsource, bytes));
            xsmodelList.add(xsGrammer.toXSModel());

        } else {
            Map schemas = serializeSchemaElements(doc);
            SchemaEntityResolver schemaResolver = (SchemaEntityResolver)preparser.getEntityResolver();
            schemaResolver.setSchemas(schemas);
            Iterator it = schemas.keySet().iterator();
            while (it.hasNext()) {
                String tns = (String)it.next();
                byte[] schemaBytes = (byte[])schemas.get(tns);
                WSDLSchemaErrorHandler schemaHandler = new WSDLSchemaErrorHandler(handler, schemaBytes, doc
                    .getXmlEncoding());

                try {
                    preparser.setErrorHandler(schemaHandler);

                    XSGrammar xsGrammer = (XSGrammar)preparser
                        .preparseGrammar(XMLGrammarDescription.XML_SCHEMA,
                                         copyInputSourceXML(wsdlsource, tns, schemaBytes, doc
                                             .getXmlEncoding()));
                    xsmodelList.add(xsGrammer.toXSModel());

                } finally {
                    preparser.setErrorHandler(handler);
                }
            }
        }
    }

    private boolean isSchemaDocument(Document doc) {
        String tagName = doc.getDocumentElement().getTagName();
        int idx = tagName.lastIndexOf(':');
        if (idx != -1) {
            tagName = tagName.substring(idx + 1, tagName.length());
        }
        return "schema".equals(tagName);
    }

    private Map<String, byte[]> serializeSchemaElements(Document doc) throws IOException {
        Map<String, byte[]> result = new HashMap<String, byte[]>();
        NodeList nodes = doc.getElementsByTagNameNS(WSDLConstants.NS_XMLNS, "schema");
        for (int x = 0; x < nodes.getLength(); x++) {
            Node schemaNode = nodes.item(x);
            Element schemaEl = (Element)schemaNode;
            String tns = schemaEl.getAttribute("targetNamespace");

            boolean clone = true;
            NamedNodeMap defAttrs = doc.getDocumentElement().getAttributes();
            for (int i = 0; i < defAttrs.getLength(); ++i) {
                Node attr = defAttrs.item(i);
                if (attr.getNodeName().startsWith("xmlns:")) {
                    if (!schemaEl.hasAttribute(attr.getNodeName()) && clone) {
                        schemaEl = (Element)(schemaNode.cloneNode(true));
                        clone = false;
                        schemaEl.setAttribute(attr.getNodeName(), attr.getNodeValue());
                    }

                    if (!schemaEl.hasAttribute(attr.getNodeName())) {
                        schemaEl.setAttribute(attr.getNodeName(), attr.getNodeValue());
                    }

                }
            }

            // Serialize the schema element.
            //
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            OutputFormat of = new OutputFormat(doc);
            XMLSerializer ser = new XMLSerializer(os, of);
            ser.serialize(schemaEl);
            os.flush();
            os.close();
            result.put(tns, os.toByteArray());
        }
        return result;
    }

    private InputSource copyInputSource(InputSource source, byte[] stream) {
        InputSource is = new InputSource(source.getSystemId());

        is.setPublicId(source.getPublicId());
        is.setEncoding(source.getEncoding());
        if (stream != null) {
            is.setByteStream(new ByteArrayInputStream(stream));
        }

        return is;
    }

    private XMLInputSource copyInputSourceXML(InputSource source, byte[] stream) {
        return copyInputSourceXML(source, stream, source.getEncoding());
    }

    private XMLInputSource copyInputSourceXML(InputSource source, byte[] stream, String encoding) {

        XMLInputSource ret = null;
        if (stream == null) {
            ret = new XMLInputSource(source.getPublicId(), source.getSystemId(), null);
        } else {
            ret = new XMLInputSource(source.getPublicId(), source.getSystemId(), null,
                                     new ByteArrayInputStream(stream), encoding);
        }
        return ret;
    }

    private XMLInputSource copyInputSourceXML(InputSource source, String tns,
                                              byte[] stream, String encoding) {

        XMLInputSource ret = null;
        if (stream == null) {
            ret = new XMLInputSource(source.getPublicId(), source.getSystemId(), null);
        } else {
            ret = new XMLInputSource(tns, tns, null, new ByteArrayInputStream(stream), encoding);
        }
        return ret;
    }

    private String[] getDefaultSchemas() {

        String loc = schemaLocation;

        if (loc == null || "".equals(loc.trim())) {
            loc = "./";
        }
        File f = new File(loc);

        if (f.exists() && f.isDirectory()) {
            FilenameFilter filter = new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    if (name.toLowerCase().endsWith(".xsd")
                        && !new File(dir.getPath() + File.separator + name).isDirectory()) {
                        return true;
                    }
                    return false;
                }
            };
            return f.list(filter);
        }
        return null;
    }

    private String getNamespaceOfSchemas(String[] schemas) throws IOException, SAXException {

        String nsSchema = "";

        for (int i = 0; i < schemas.length; i++) {
            String url = null;
            url = getSchemaUrl(schemas[i]);
            DOMParser p = new DOMParser();
            p.parse(url);

            String tns = p.getDocument().getDocumentElement().getAttribute("targetNamespace");
            nsSchema += tns + " " + url + " ";
        }
        return nsSchema;
    }

    private void setExternalSchemaLocations(String[] schemas) throws IOException, SAXException {
        String nsSchemas = getNamespaceOfSchemas(schemas);
        parser.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", nsSchemas);
        preparser.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", nsSchemas);
    }

    private StackTraceErrorHandler setErrorHandler() {
        StackTraceErrorHandler handler = new StackTraceErrorHandler();
        setErrorHandler(handler);
        return handler;
    }

    private StackTraceErrorHandler getErrorHandler() {
        return (StackTraceErrorHandler)parser.getErrorHandler();
    }

    private String getUrlFromString(String path) throws IOException {
        URL url = null;
        try {
            url = new URL(path);
        } catch (MalformedURLException mfex) {
            try {
                File f = new File(path);
                if (f.exists() && !f.isDirectory()) {
                    url = f.toURL();
                }
            } catch (Exception fnex) {
                // ignorable
            }
        } catch (Exception ex) {
            // ignorable
        }
        return (url == null) ? null : url.toString();
    }

    private URL getURL(String path) throws IOException {
        URL url = null;

        if (path == null) {
            return url;
        }
        try {
            url = URLFactory.createURL(path);
        } catch (MalformedURLException mfex) {
            File f = new File(path);
            url = f.toURL();
        }

        return url;
    }

    private String getUrlFromString(String base, String path) throws IOException {
        if (base != null) {
            URL url = getURL(base);
            if (path.indexOf(":") != -1) {
                URL tmpurl = getURL(path);
                if (tmpurl != null) {
                    path = tmpurl.toString();
                }
            }
            return new URL(url, path).toString();
        }
        return getUrlFromString(path);
    }

    private String resolveUrl(String path) throws IOException {
        return resolveUrl(null, path);
    }

    private String resolveUrl(String base, String path) throws IOException {
        String url = getUrlFromString(base, path);
        if (url == null) {
            url = getUrlFromString(schemaLocation, path);
        }
        return url;
    }

    private String getSchemaUrl(String path) throws IOException {
        String url = getUrlFromString(path);
        if (url == null && schemaLocation != null && !"".equals(schemaLocation.trim())) {

            url = getUrlFromString(schemaLocation, path);
        }

        if (url == null) {
            throw new IOException("The URL or filename for the specified schema does not exist: " + path);
        }

        return url;
    }

    private String getWsdlUrl(String path) throws IOException {
        return getWsdlUrl(null, path);
    }

    private String getWsdlUrl(String base, String path) throws IOException {
        String url = resolveUrl(base, path);

        if (url == null) {
            throw new IOException("The URL or filename for the specified WSDL does not exist: " + path);
        }

        return url;
    }

    class SchemaEntityResolver implements XMLEntityResolver {

        Map schemas;

        public void setSchemas(Map schemaMap) {
            schemas = schemaMap;
        }

        public XMLInputSource resolveEntity(XMLResourceIdentifier id) throws XNIException, IOException {
            if (id.getLiteralSystemId() != null) {
                String url = resolveUrl(id.getBaseSystemId(), id.getLiteralSystemId());
                if (url == null) {
                    String msg = "Can't resolve entity from publicID=" + id.getPublicId() + ", systemID="
                                 + id.getLiteralSystemId();

                    throw new IOException(msg);
                }
                return new XMLInputSource(id.getPublicId(), url, id.getBaseSystemId());
            } else {
                // Means the schema is in the same wsdl document
                String ns = id.getNamespace();
                byte[] schemaBytes = (byte[])schemas.get(ns);
                if (schemaBytes != null) {
                    return new XMLInputSource(id.getPublicId(), id.getLiteralSystemId(),
                                              id.getBaseSystemId(), new ByteArrayInputStream(schemaBytes),
                                              "UTF-8");
                } else {
                    return null;
                }
            }
        }

    }

    public List<XSModel> getXSModelList() {
        return xsmodelList;
    }

    public Document getSchemaValidatedDoc() {
        return schemaValidatedDoc;
    }
   
    public Map<QName , List> getMsgPartsMap() {
        return msgPartsMap;
    }
   
    public Map<QName , Map> getPortTypesMap() {
        return portTypes;
    }
   
    public Map<QName , QName> getBindingMap() {
        return bindingMap;
    }
  
   
}

class StackTraceErrorHandler implements ErrorHandler, XMLErrorHandler {
    protected boolean valid;
    private StringBuffer buffer;
    private int numErrors;
    private List<SAXParseException> errors;

    StackTraceErrorHandler() {
        valid = true;
        numErrors = 0;
        buffer = new StringBuffer();
        errors = new ArrayList<SAXParseException>();
    }

    public void error(SAXParseException ex) {
        addError(ex);
    }

    public void fatalError(SAXParseException ex) {
        addError(ex);
    }

    public void warning(SAXParseException ex) {
        // Warning messages are ignored.
        // return;
    }

    public void error(String domain, String key, XMLParseException ex) {
        addError(getSAXParseException(ex));
    }

    public void fatalError(String domain, String key, XMLParseException ex) {
        addError(getSAXParseException(ex));
    }

    public void warning(String domain, String key, XMLParseException ex) {
        // Warning messages are ignored.
        // return;
    }

    boolean isValid() {
        return valid;
    }

    int getTotalErrors() {
        return numErrors;
    }

    String getErrorMessages() {
        return buffer.toString();
    }

    SAXParseException[] getErrors() {
        if (errors == null) {
            return null;
        }
        return errors.toArray(new SAXParseException[errors.size()]);
    }

    void addError(String msg, SAXParseException ex) {
        valid = false;
        if (numErrors == 0) {
            buffer.append("\n");
        } else {
            buffer.append("\n\n");
        }
        buffer.append(msg);
        numErrors++;
        errors.add(ex);

    }

    private String getErrorMessage(SAXParseException ex) {
        return "line " + ex.getLineNumber() + " column " + ex.getColumnNumber() + " of " + ex.getSystemId()
               + ": " + ex.getMessage();
    }

    private void addError(SAXParseException ex) {
        addError(getErrorMessage(ex), ex);
    }

    private static SAXParseException getSAXParseException(XMLParseException ex) {
        return new SAXParseException(ex.getMessage(), ex.getPublicId(), ex.getLiteralSystemId(), ex
            .getLineNumber(), ex.getColumnNumber(), ex.getException());
    }
}

class WSDLSchemaErrorHandler implements XMLErrorHandler {
    private StackTraceErrorHandler handler;
    private String schemaText;

    WSDLSchemaErrorHandler(StackTraceErrorHandler hand, byte[] schemaBytes, String schemaEncoding) {
        this.handler = hand;
        try {
            schemaText = new String(schemaBytes, schemaEncoding);
        } catch (java.io.UnsupportedEncodingException ex) {
            // ignoreable
        }
    }

    public void error(String domain, String key, XMLParseException ex) {
        handler.addError(getErrorMessage(ex), getSAXParseException(ex));
    }

    public void fatalError(String domain, String key, XMLParseException ex) {
        handler.addError(getErrorMessage(ex), getSAXParseException(ex));
    }

    public void warning(String domain, String key, XMLParseException ex) {
        // Warning messages are ignored.
        // return;
    }

    private String getErrorMessage(XMLParseException ex) {
        String msg = null;
        if (schemaText != null) {
            int lineNumber = ex.getLineNumber();
            int start = 0;
            int end = schemaText.indexOf('\n');
            int idx = 1;
            while (end != -1 && idx < lineNumber) {
                start = end + 1;
                end = schemaText.indexOf('\n', start);
                ++idx;
            }
            if (end == -1) {
                end = schemaText.length();
            }

            if (idx == lineNumber) {
                msg = "line \"" + schemaText.substring(start, end).trim() + "\" in the schema of "
                      + ex.getLiteralSystemId() + ": " + ex.getMessage();
            }
        }

        if (msg == null) {
            msg = ex.getLiteralSystemId() + ": " + ex.getMessage();
        }

        return msg;
    }

    private static SAXParseException getSAXParseException(XMLParseException ex) {
        return new SAXParseException(ex.getMessage(), ex.getPublicId(), ex.getLiteralSystemId(), -1, -1, ex
            .getException());
    }

}
TOP

Related Classes of org.objectweb.celtix.tools.processors.wsdl2.validators.SchemaWSDLValidator

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.