All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kohsuke.rngom.rngparser.digested.DXMLPrinter Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 * Copyright (C) 2004-2011
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.kohsuke.rngom.rngparser.digested;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.kohsuke.rngom.rngparser.ast.builder.BuildException;
import org.kohsuke.rngom.rngparser.ast.builder.SchemaBuilder;
import org.kohsuke.rngom.rngparser.ast.util.CheckingSchemaBuilder;
import org.kohsuke.rngom.rngparser.nc.NameClass;
import org.kohsuke.rngom.rngparser.nc.NameClassVisitor;
import org.kohsuke.rngom.rngparser.nc.SimpleNameClass;
import org.kohsuke.rngom.rngparser.parse.Parseable;
import org.kohsuke.rngom.rngparser.parse.compact.CompactParseable;
import org.kohsuke.rngom.rngparser.parse.xml.SAXParseable;
import org.kohsuke.rngom.rngparser.xml.util.WellKnownNamespaces;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Printer of RELAX NG digested model to XML using StAX {@link XMLStreamWriter}.
 *
 * @author Alexey Demakov
 */
public class DXMLPrinter {
    protected XMLStreamWriter out;
    protected String indentStep = "\t";
    protected String newLine = System.getProperty("line.separator");
    protected int indent;
    protected boolean afterEnd = false;
    protected DXMLPrinterVisitor visitor;
    protected NameClassXMLPrinterVisitor ncVisitor;
    protected DOMPrinter domPrinter;

    /**
     * @param out Output stream.
     */
    public DXMLPrinter(XMLStreamWriter out) {
        this.out = out;
        this.visitor = new DXMLPrinterVisitor();
        this.ncVisitor = new NameClassXMLPrinterVisitor();
        this.domPrinter = new DOMPrinter(out);
    }

    /**
     * Prints grammar enclosed by start/end document.
     *
     * @param grammar
     * @throws XMLStreamException
     */
    public void printDocument(DGrammarPattern grammar) throws XMLStreamException {
        try {
            visitor.startDocument();
            visitor.on(grammar);
            visitor.endDocument();
        } catch (XMLWriterException e) {
            throw (XMLStreamException) e.getCause();
        }
    }

    /**
     * Prints XML fragment for the given pattern.
     *
     * @throws XMLStreamException
     */
    public void print(DPattern pattern) throws XMLStreamException {
        try {
            pattern.accept(visitor);
        } catch (XMLWriterException e) {
            throw (XMLStreamException) e.getCause();
        }
    }

    /**
     * Prints XML fragment for the given name class.
     *
     * @throws XMLStreamException
     */
    public void print(NameClass nc) throws XMLStreamException {
        try {
            nc.accept(ncVisitor);
        } catch (XMLWriterException e) {
            throw (XMLStreamException) e.getCause();
        }
    }

    public void print(Node node) throws XMLStreamException {
        domPrinter.print(node);
    }

    protected class XMLWriterException extends RuntimeException {
        protected XMLWriterException(Throwable cause) {
            super(cause);
        }
    }

    protected class XMLWriter {
        protected void newLine() {
            try {
                out.writeCharacters(newLine);
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        protected void indent() {
            try {
                for (int i = 0; i < indent; i++) {
                    out.writeCharacters(indentStep);
                }
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void startDocument() {
            try {
                out.writeStartDocument();
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void endDocument() {
            try {
                out.writeEndDocument();
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public final void start(String element) {
            try {
                newLine();
                indent();
                out.writeStartElement(element);
                indent++;
                afterEnd = false;
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void end() {
            try {
                indent--;
                if (afterEnd) {
                    newLine();
                    indent();
                }
                out.writeEndElement();
                afterEnd = true;
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void attr(String prefix, String ns, String name, String value) {
            try {
                out.writeAttribute(prefix, ns, name, value);
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void attr(String name, String value) {
            try {
                out.writeAttribute(name, value);
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void ns(String prefix, String uri) {
            try {
                out.writeNamespace(prefix, uri);
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }

        public void body(String text) {
            try {
                out.writeCharacters(text);
                afterEnd = false;
            } catch (XMLStreamException e) {
                throw new XMLWriterException(e);
            }
        }
    }

    protected class DXMLPrinterVisitor extends XMLWriter implements DPatternVisitor {
        protected void on(DPattern p) {
            p.accept(this);
        }

        protected void unwrapGroup(DPattern p) {
            if (p instanceof DGroupPattern && p.getAnnotation() == DAnnotation.EMPTY) {
                for (DPattern d : (DGroupPattern) p) {
                    on(d);
                }
            } else {
                on(p);
            }
        }

        protected void unwrapChoice(DPattern p) {
            if (p instanceof DChoicePattern && p.getAnnotation() == DAnnotation.EMPTY) {
                for (DPattern d : (DChoicePattern) p) {
                    on(d);
                }
            } else {
                on(p);
            }
        }

        protected void on(NameClass nc) {
            if (nc instanceof SimpleNameClass) {
                QName qname = ((SimpleNameClass) nc).name;
                String name = qname.getLocalPart();
                if (!qname.getPrefix().equals("")) name = qname.getPrefix() + ":";
                attr("name", name);
            } else {
                nc.accept(ncVisitor);
            }
        }

        protected void on(DAnnotation ann) {
        	// FIXEDBYME 
//            if (ann == DAnnotation.EMPTY) return;
//            for (DAnnotation.Attribute attr : ann.getAttributes().values()) {
//                attr(attr.getPrefix(), attr.getNs(), attr.getLocalName(), attr.getValue());
//            }
//            for (Element elem : ann.getChildren()) {
//                try {
//                    newLine();
//                    indent();
//                    print(elem);
//                }
//                catch (XMLStreamException e) {
//                    throw new XMLWriterException(e);
//                }
//            }
        }

        public Void onAttribute(DAttributePattern p) {
            start("attribute");
            on(p.getName());
            on(p.getAnnotation());
            DPattern child = p.getChild();
            // do not print default value
            if (!(child instanceof DTextPattern)) {
                on(p.getChild());
            }
            end();
            return null;
        }

        public Void onChoice(DChoicePattern p) {
            start("choice");
            on(p.getAnnotation());
            for (DPattern d : p) {
                on(d);
            }
            end();
            return null;
        }

        public Void onData(DDataPattern p) {
            List params = p.getParams();
            DPattern except = p.getExcept();
            start("data");
            attr("datatypeLibrary", p.getDatatypeLibrary());
            attr("type", p.getType());
            on(p.getAnnotation());
            for (DDataPattern.Param param : params) {
                start("param");
                attr("ns", param.getNs());
                attr("name", param.getName());
                body(param.getValue());
                end();
            }
            if (except != null) {
                start("except");
                unwrapChoice(except);
                end();
            }
            end();
            return null;
        }

        public Void onElement(DElementPattern p) {
            start("element");
            on(p.getName());
            on(p.getAnnotation());
            unwrapGroup(p.getChild());
            end();
            return null;
        }

        public Void onEmpty(DEmptyPattern p) {
            start("empty");
            on(p.getAnnotation());
            end();
            return null;
        }

        public Void onGrammar(DGrammarPattern p) {
            start("grammar");
            ns(null, WellKnownNamespaces.RELAX_NG);
            on(p.getAnnotation());
            start("start");
            on(p.getStart());
            end();
            for (DDefine d : p) {
                start("define");
                attr("name", d.getName());
                on(d.getAnnotation());
                unwrapGroup(d.getPattern());
                end();
            }
            end();
            return null;
        }

        public Void onGroup(DGroupPattern p) {
            start("group");
            on(p.getAnnotation());
            for (DPattern d : p) {
                on(d);
            }
            end();
            return null;
        }

        public Void onInterleave(DInterleavePattern p) {
            start("interleave");
            on(p.getAnnotation());
            for (DPattern d : p) {
                on(d);
            }
            end();
            return null;
        }

        public Void onList(DListPattern p) {
            start("list");
            on(p.getAnnotation());
            unwrapGroup(p.getChild());
            end();
            return null;
        }

        public Void onMixed(DMixedPattern p) {
            start("mixed");
            on(p.getAnnotation());
            unwrapGroup(p.getChild());
            end();
            return null;
        }

        public Void onNotAllowed(DNotAllowedPattern p) {
            start("notAllowed");
            on(p.getAnnotation());
            end();
            return null;
        }

        public Void onOneOrMore(DOneOrMorePattern p) {
            start("oneOrMore");
            on(p.getAnnotation());
            unwrapGroup(p.getChild());
            end();
            return null;
        }

        public Void onOptional(DOptionalPattern p) {
            start("optional");
            on(p.getAnnotation());
            unwrapGroup(p.getChild());
            end();
            return null;
        }

        public Void onRef(DRefPattern p) {
            start("ref");
            attr("name", p.getName());
            on(p.getAnnotation());
            end();
            return null;
        }

        public Void onText(DTextPattern p) {
            start("text");
            on(p.getAnnotation());
            end();
            return null;
        }

        public Void onValue(DValuePattern p) {
            start("value");
            if (!p.getNs().equals("")) attr("ns", p.getNs());
            attr("datatypeLibrary", p.getDatatypeLibrary());
            attr("type", p.getType());
            on(p.getAnnotation());
            body(p.getValue());
            end();
            return null;
        }

        public Void onZeroOrMore(DZeroOrMorePattern p) {
            start("zeroOrMore");
            on(p.getAnnotation());
            unwrapGroup(p.getChild());
            end();
            return null;
        }
    }

    protected class NameClassXMLPrinterVisitor extends XMLWriter implements NameClassVisitor {
        public Void visitChoice(NameClass nc1, NameClass nc2) {
            // TODO: flatten nested choices
            start("choice");
            nc1.accept(this);
            nc2.accept(this);
            end();
            return null;
        }

        public Void visitNsName(String ns) {
            start("nsName");
            attr("ns", ns);
            end();
            return null;
        }

        public Void visitNsNameExcept(String ns, NameClass nc) {
            start("nsName");
            attr("ns", ns);
            start("except");
            nc.accept(this);
            end();
            end();
            return null;
        }

        public Void visitAnyName() {
            start("anyName");
            end();
            return null;
        }

        public Void visitAnyNameExcept(NameClass nc) {
            start("anyName");
            start("except");
            nc.accept(this);
            end();
            end();
            return null;
        }

        public Void visitName(QName name) {
            start("name");
            if (!name.getPrefix().equals("")) {
                body(name.getPrefix() + ":");
            }
            body(name.getLocalPart());
            end();
            return null;
        }

        public Void visitNull() {
            throw new UnsupportedOperationException("visitNull");
        }
    }
    // Harshit : Removed test case using public static void main(String[] args)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy