Package hu.sztaki.ilab.longneck.bootstrap

Source Code of hu.sztaki.ilab.longneck.bootstrap.XMLDocumentLoader$ParserFactory

package hu.sztaki.ilab.longneck.bootstrap;

import hu.sztaki.ilab.longneck.process.FileType;
import hu.sztaki.ilab.longneck.process.SourceInfo;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.*;
import javax.xml.validation.Schema;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;

/**
*
* @author Molnár Péter <molnarp@sztaki.mta.hu>
*/
public class XMLDocumentLoader implements ResourceLoaderAware {
    /** The Longneck namespace URI. */
    public static final String NS = "urn:hu.sztaki.ilab.longneck:1.0";
    public static final String NS_XSI = "http://www.w3.org/2001/XMLSchema-instance";
   
    /** The schema loader to load the schema. */
    private SchemaLoader schemaLoader;
    /** The SAX document loader factory. */
    private ParserFactory parserFactory = null;
    /** Resource loader to load resources. */
    private ResourceLoader resourceLoader;
   
    public Document getDocument(Resource r, FileType type) throws IOException,
            ParserConfigurationException, SAXException {
        if (parserFactory == null) {
            parserFactory = new ParserFactory();
        }
       
        SAXParser parser = null;
        URL schemaUrl = resourceLoader.getResource(SchemaPath.forType(type)).getURL();
       
        try {
            parser = parserFactory.getSAXParser(schemaUrl);
        } catch (ParserConfigurationException ex) {
            throw new RuntimeException(ex);
        } catch (SAXException ex) {
            throw new RuntimeException(ex);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
       
        DOMBuilder builder = new DOMBuilder(r.getURL().toExternalForm());
        parser.parse(r.getInputStream(), builder);
       
        return builder.getDocument();
    }
   
    public SchemaLoader getSchemaLoader() {
        return schemaLoader;
    }

    public void setSchemaLoader(SchemaLoader schemaLoader) {
        this.schemaLoader = schemaLoader;
    }

    @Override
    public void setResourceLoader(ResourceLoader rl) {
        this.resourceLoader = rl;
    }
   
   

    private class ParserFactory {
       
        private SAXParserFactory saxParserFactory;
        Map<String,SAXParser> saxParsers;
      
        public ParserFactory() {
            saxParserFactory = SAXParserFactory.newInstance();
            saxParserFactory.setNamespaceAware(true);
            //saxParserFactory.setValidating(true);
           
            saxParsers = new HashMap<String,SAXParser>();
        }
       
       
        public SAXParser getSAXParser(URL schemaUrl) throws ParserConfigurationException,
                SAXException, IOException {
            SAXParser saxParser;
            if (saxParsers.containsKey(schemaUrl.toString())) {
                saxParser = saxParsers.get(schemaUrl.toString());
            } else {
                Schema schema;

                // Entity file parser
                schema = schemaLoader.getSchema(schemaUrl);
                saxParserFactory.setSchema(schema);
                saxParser = saxParserFactory.newSAXParser();

                saxParsers.put(schemaUrl.toString(), saxParser);
            }
           
            return saxParser;
        }
    }
   
    private static class DOMBuilder extends DefaultHandler2 {

        /** The document, which is loaded. */
        private final String documentUrl;
        /** The sequence counter for elements. */
        private int sequenceCounter;
        /** The currently active container block id. */
        private final Deque<String> blockStack = new ArrayDeque<String>();
        /** The locator to query location in the XML document. */
        private Locator locator;

        /** The document builder. */
        private DocumentBuilder docBuilder;
        /** The currently built document. */
        private Document document;
        /** The current node in the tree. */
        private Node current;
        /** The prefix mapping. */
        private Map<String,String> prefixMap = new HashMap<String,String>();

        public DOMBuilder(String documentUrl) throws ParserConfigurationException {
            this.documentUrl = documentUrl;
           
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            docBuilder = dbf.newDocumentBuilder();
        }

        public Document getDocument() {
            return document;
        }
       
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
           
            document = docBuilder.newDocument();
            current = document;
            sequenceCounter = 0;
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes)
                throws SAXException {
            super.startElement(uri, localName, qName, attributes);
           
            // Create element
            Element element = document.createElementNS(uri, qName);
           
            // Copy attributes
            for (int i = 0; i < attributes.getLength(); ++i) {               
                // Fix fog bug http://jira.codehaus.org/browse/CASTOR-2813
                if (NS_XSI.equals(attributes.getURI(i))) {
                    continue;
                }
               
                element.setAttributeNS(attributes.getURI(i), attributes.getQName(i), attributes.getValue(i));
            }
           
            // Save container block id, if available.
            if (NS.equals(uri) && "block".equals(localName)) {
                blockStack.addLast(String.format("%1$s:%2$s",
                        attributes.getValue("id"), attributes.getValue("version")));
            }

            // Create source info and add serialized form as attribute.
            SourceInfo pframe = new SourceInfo(documentUrl,
                    (! blockStack.isEmpty()) ? blockStack.peekLast() : null,
                    sequenceCounter, locator.getLineNumber(), locator.getColumnNumber());
            element.setAttribute("source-info", pframe.toJSONString());

            // Increase sequence counter.
            ++sequenceCounter;
           
            // Add and set current
            current.appendChild(element);
            current = element;
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
           
            current = current.getParentNode();
           
            if (NS.equals(uri) && "block".equals(localName) && blockStack.size() > 0) {
                blockStack.removeLast();
            }
        }

        @Override
        public void startPrefixMapping(String prefix, String uri) throws SAXException {
            super.startPrefixMapping(prefix, uri);
           
            prefixMap.put(uri, prefix);
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
           
            current.appendChild(document.createTextNode(String.copyValueOf(ch, start, length)));
        }

        @Override
        public void comment(char[] ch, int start, int length) throws SAXException {
            super.comment(ch, start, length);
           
            current.appendChild(document.createComment(String.copyValueOf(ch, start, length)));
        }

        @Override
        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
            super.ignorableWhitespace(ch, start, length);
           
            current.appendChild(document.createTextNode(String.copyValueOf(ch, start, length)));
        }

        @Override
        public void processingInstruction(String target, String data) throws SAXException {
            super.processingInstruction(target, data);
           
            current.appendChild(document.createProcessingInstruction(target, data));
        }
       
        @Override
        public void setDocumentLocator(Locator locator) {
            super.setDocumentLocator(locator);
            this.locator = locator;
        }
       
        @Override
        public void error(org.xml.sax.SAXParseException err) throws org.xml.sax.SAXParseException {
            System.out.println("** ERROR" + ", line " + err.getLineNumber()
                    + ", uri " + err.getSystemId());
            System.out.println("   " + err.getMessage());
            throw err;
        }

        @Override
        public void warning(org.xml.sax.SAXParseException err) throws org.xml.sax.SAXParseException {
            System.out.println("** Warning" + ", line " + err.getLineNumber()
                    + ", uri " + err.getSystemId());
            System.out.println("   " + err.getMessage());
        }
       
    }
}
TOP

Related Classes of hu.sztaki.ilab.longneck.bootstrap.XMLDocumentLoader$ParserFactory

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.