src/share/jaxws_classes/com/sun/xml/internal/rngom/digested/DXMLPrinter.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 408
b0610cd08440
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 /*
    26  * Copyright (C) 2004-2011
    27  *
    28  * Permission is hereby granted, free of charge, to any person obtaining a copy
    29  * of this software and associated documentation files (the "Software"), to deal
    30  * in the Software without restriction, including without limitation the rights
    31  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    32  * copies of the Software, and to permit persons to whom the Software is
    33  * furnished to do so, subject to the following conditions:
    34  *
    35  * The above copyright notice and this permission notice shall be included in
    36  * all copies or substantial portions of the Software.
    37  *
    38  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    39  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    40  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    41  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    42  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    43  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    44  * THE SOFTWARE.
    45  */
    46 package com.sun.xml.internal.rngom.digested;
    48 import java.io.File;
    49 import java.io.FileOutputStream;
    50 import java.io.OutputStream;
    51 import java.util.List;
    53 import javax.xml.namespace.QName;
    54 import javax.xml.stream.XMLOutputFactory;
    55 import javax.xml.stream.XMLStreamException;
    56 import javax.xml.stream.XMLStreamWriter;
    58 import com.sun.xml.internal.rngom.ast.builder.BuildException;
    59 import com.sun.xml.internal.rngom.ast.builder.SchemaBuilder;
    60 import com.sun.xml.internal.rngom.ast.util.CheckingSchemaBuilder;
    61 import com.sun.xml.internal.rngom.nc.NameClass;
    62 import com.sun.xml.internal.rngom.nc.NameClassVisitor;
    63 import com.sun.xml.internal.rngom.nc.SimpleNameClass;
    64 import com.sun.xml.internal.rngom.parse.Parseable;
    65 import com.sun.xml.internal.rngom.parse.compact.CompactParseable;
    66 import com.sun.xml.internal.rngom.parse.xml.SAXParseable;
    67 import com.sun.xml.internal.rngom.xml.util.WellKnownNamespaces;
    68 import org.w3c.dom.Element;
    69 import org.w3c.dom.Node;
    70 import org.xml.sax.ErrorHandler;
    71 import org.xml.sax.InputSource;
    72 import org.xml.sax.SAXException;
    73 import org.xml.sax.SAXParseException;
    74 import org.xml.sax.helpers.DefaultHandler;
    76 /**
    77  * Printer of RELAX NG digested model to XML using StAX {@link XMLStreamWriter}.
    78  *
    79  * @author <A href="mailto:demakov@ispras.ru">Alexey Demakov</A>
    80  */
    81 public class DXMLPrinter {
    82     protected XMLStreamWriter out;
    83     protected String indentStep = "\t";
    84     protected String newLine = System.getProperty("line.separator");
    85     protected int indent;
    86     protected boolean afterEnd = false;
    87     protected DXMLPrinterVisitor visitor;
    88     protected NameClassXMLPrinterVisitor ncVisitor;
    89     protected DOMPrinter domPrinter;
    91     /**
    92      * @param out Output stream.
    93      */
    94     public DXMLPrinter(XMLStreamWriter out) {
    95         this.out = out;
    96         this.visitor = new DXMLPrinterVisitor();
    97         this.ncVisitor = new NameClassXMLPrinterVisitor();
    98         this.domPrinter = new DOMPrinter(out);
    99     }
   101     /**
   102      * Prints grammar enclosed by start/end document.
   103      *
   104      * @param grammar
   105      * @throws XMLStreamException
   106      */
   107     public void printDocument(DGrammarPattern grammar) throws XMLStreamException {
   108         try {
   109             visitor.startDocument();
   110             visitor.on(grammar);
   111             visitor.endDocument();
   112         } catch (XMLWriterException e) {
   113             if (e.getCause() instanceof XMLStreamException) {
   114                 throw (XMLStreamException) e.getCause();
   115             } else {
   116                 throw new XMLStreamException(e);
   117             }
   118         }
   119     }
   121     /**
   122      * Prints XML fragment for the given pattern.
   123      *
   124      * @throws XMLStreamException
   125      */
   126     public void print(DPattern pattern) throws XMLStreamException {
   127         try {
   128             pattern.accept(visitor);
   129         } catch (XMLWriterException e) {
   130             if (e.getCause() instanceof XMLStreamException) {
   131                 throw (XMLStreamException) e.getCause();
   132             } else {
   133                 throw new XMLStreamException(e);
   134             }
   135         }
   136     }
   138     /**
   139      * Prints XML fragment for the given name class.
   140      *
   141      * @throws XMLStreamException
   142      */
   143     public void print(NameClass nc) throws XMLStreamException {
   144         try {
   145             nc.accept(ncVisitor);
   146         } catch (XMLWriterException e) {
   147             if (e.getCause() instanceof XMLStreamException) {
   148                 throw (XMLStreamException) e.getCause();
   149             } else {
   150                 throw new XMLStreamException(e);
   151             }
   152         }
   153     }
   155     public void print(Node node) throws XMLStreamException {
   156         domPrinter.print(node);
   157     }
   159     protected class XMLWriterException extends RuntimeException {
   160         protected XMLWriterException(Throwable cause) {
   161             super(cause);
   162         }
   163     }
   165     protected class XMLWriter {
   166         protected void newLine() {
   167             try {
   168                 out.writeCharacters(newLine);
   169             } catch (XMLStreamException e) {
   170                 throw new XMLWriterException(e);
   171             }
   172         }
   174         protected void indent() {
   175             try {
   176                 for (int i = 0; i < indent; i++) {
   177                     out.writeCharacters(indentStep);
   178                 }
   179             } catch (XMLStreamException e) {
   180                 throw new XMLWriterException(e);
   181             }
   182         }
   184         public void startDocument() {
   185             try {
   186                 out.writeStartDocument();
   187             } catch (XMLStreamException e) {
   188                 throw new XMLWriterException(e);
   189             }
   190         }
   192         public void endDocument() {
   193             try {
   194                 out.writeEndDocument();
   195             } catch (XMLStreamException e) {
   196                 throw new XMLWriterException(e);
   197             }
   198         }
   200         public final void start(String element) {
   201             try {
   202                 newLine();
   203                 indent();
   204                 out.writeStartElement(element);
   205                 indent++;
   206                 afterEnd = false;
   207             } catch (XMLStreamException e) {
   208                 throw new XMLWriterException(e);
   209             }
   210         }
   212         public void end() {
   213             try {
   214                 indent--;
   215                 if (afterEnd) {
   216                     newLine();
   217                     indent();
   218                 }
   219                 out.writeEndElement();
   220                 afterEnd = true;
   221             } catch (XMLStreamException e) {
   222                 throw new XMLWriterException(e);
   223             }
   224         }
   226         public void attr(String prefix, String ns, String name, String value) {
   227             try {
   228                 out.writeAttribute(prefix, ns, name, value);
   229             } catch (XMLStreamException e) {
   230                 throw new XMLWriterException(e);
   231             }
   232         }
   234         public void attr(String name, String value) {
   235             try {
   236                 out.writeAttribute(name, value);
   237             } catch (XMLStreamException e) {
   238                 throw new XMLWriterException(e);
   239             }
   240         }
   242         public void ns(String prefix, String uri) {
   243             try {
   244                 out.writeNamespace(prefix, uri);
   245             } catch (XMLStreamException e) {
   246                 throw new XMLWriterException(e);
   247             }
   248         }
   250         public void body(String text) {
   251             try {
   252                 out.writeCharacters(text);
   253                 afterEnd = false;
   254             } catch (XMLStreamException e) {
   255                 throw new XMLWriterException(e);
   256             }
   257         }
   258     }
   260     protected class DXMLPrinterVisitor extends XMLWriter implements DPatternVisitor<Void> {
   261         protected void on(DPattern p) {
   262             p.accept(this);
   263         }
   265         protected void unwrapGroup(DPattern p) {
   266             if (p instanceof DGroupPattern && p.getAnnotation() == DAnnotation.EMPTY) {
   267                 for (DPattern d : (DGroupPattern) p) {
   268                     on(d);
   269                 }
   270             } else {
   271                 on(p);
   272             }
   273         }
   275         protected void unwrapChoice(DPattern p) {
   276             if (p instanceof DChoicePattern && p.getAnnotation() == DAnnotation.EMPTY) {
   277                 for (DPattern d : (DChoicePattern) p) {
   278                     on(d);
   279                 }
   280             } else {
   281                 on(p);
   282             }
   283         }
   285         protected void on(NameClass nc) {
   286             if (nc instanceof SimpleNameClass) {
   287                 QName qname = ((SimpleNameClass) nc).name;
   288                 String name = qname.getLocalPart();
   289                 if (!qname.getPrefix().equals("")) name = qname.getPrefix() + ":";
   290                 attr("name", name);
   291             } else {
   292                 nc.accept(ncVisitor);
   293             }
   294         }
   296         protected void on(DAnnotation ann) {
   297             if (ann == DAnnotation.EMPTY) return;
   298             for (DAnnotation.Attribute attr : ann.getAttributes().values()) {
   299                 attr(attr.getPrefix(), attr.getNs(), attr.getLocalName(), attr.getValue());
   300             }
   301             for (Element elem : ann.getChildren()) {
   302                 try {
   303                     newLine();
   304                     indent();
   305                     print(elem);
   306                 }
   307                 catch (XMLStreamException e) {
   308                     throw new XMLWriterException(e);
   309                 }
   310             }
   311         }
   313         public Void onAttribute(DAttributePattern p) {
   314             start("attribute");
   315             on(p.getName());
   316             on(p.getAnnotation());
   317             DPattern child = p.getChild();
   318             // do not print default value
   319             if (!(child instanceof DTextPattern)) {
   320                 on(p.getChild());
   321             }
   322             end();
   323             return null;
   324         }
   326         public Void onChoice(DChoicePattern p) {
   327             start("choice");
   328             on(p.getAnnotation());
   329             for (DPattern d : p) {
   330                 on(d);
   331             }
   332             end();
   333             return null;
   334         }
   336         public Void onData(DDataPattern p) {
   337             List<DDataPattern.Param> params = p.getParams();
   338             DPattern except = p.getExcept();
   339             start("data");
   340             attr("datatypeLibrary", p.getDatatypeLibrary());
   341             attr("type", p.getType());
   342             on(p.getAnnotation());
   343             for (DDataPattern.Param param : params) {
   344                 start("param");
   345                 attr("ns", param.getNs());
   346                 attr("name", param.getName());
   347                 body(param.getValue());
   348                 end();
   349             }
   350             if (except != null) {
   351                 start("except");
   352                 unwrapChoice(except);
   353                 end();
   354             }
   355             end();
   356             return null;
   357         }
   359         public Void onElement(DElementPattern p) {
   360             start("element");
   361             on(p.getName());
   362             on(p.getAnnotation());
   363             unwrapGroup(p.getChild());
   364             end();
   365             return null;
   366         }
   368         public Void onEmpty(DEmptyPattern p) {
   369             start("empty");
   370             on(p.getAnnotation());
   371             end();
   372             return null;
   373         }
   375         public Void onGrammar(DGrammarPattern p) {
   376             start("grammar");
   377             ns(null, WellKnownNamespaces.RELAX_NG);
   378             on(p.getAnnotation());
   379             start("start");
   380             on(p.getStart());
   381             end();
   382             for (DDefine d : p) {
   383                 start("define");
   384                 attr("name", d.getName());
   385                 on(d.getAnnotation());
   386                 unwrapGroup(d.getPattern());
   387                 end();
   388             }
   389             end();
   390             return null;
   391         }
   393         public Void onGroup(DGroupPattern p) {
   394             start("group");
   395             on(p.getAnnotation());
   396             for (DPattern d : p) {
   397                 on(d);
   398             }
   399             end();
   400             return null;
   401         }
   403         public Void onInterleave(DInterleavePattern p) {
   404             start("interleave");
   405             on(p.getAnnotation());
   406             for (DPattern d : p) {
   407                 on(d);
   408             }
   409             end();
   410             return null;
   411         }
   413         public Void onList(DListPattern p) {
   414             start("list");
   415             on(p.getAnnotation());
   416             unwrapGroup(p.getChild());
   417             end();
   418             return null;
   419         }
   421         public Void onMixed(DMixedPattern p) {
   422             start("mixed");
   423             on(p.getAnnotation());
   424             unwrapGroup(p.getChild());
   425             end();
   426             return null;
   427         }
   429         public Void onNotAllowed(DNotAllowedPattern p) {
   430             start("notAllowed");
   431             on(p.getAnnotation());
   432             end();
   433             return null;
   434         }
   436         public Void onOneOrMore(DOneOrMorePattern p) {
   437             start("oneOrMore");
   438             on(p.getAnnotation());
   439             unwrapGroup(p.getChild());
   440             end();
   441             return null;
   442         }
   444         public Void onOptional(DOptionalPattern p) {
   445             start("optional");
   446             on(p.getAnnotation());
   447             unwrapGroup(p.getChild());
   448             end();
   449             return null;
   450         }
   452         public Void onRef(DRefPattern p) {
   453             start("ref");
   454             attr("name", p.getName());
   455             on(p.getAnnotation());
   456             end();
   457             return null;
   458         }
   460         public Void onText(DTextPattern p) {
   461             start("text");
   462             on(p.getAnnotation());
   463             end();
   464             return null;
   465         }
   467         public Void onValue(DValuePattern p) {
   468             start("value");
   469             if (!p.getNs().equals("")) attr("ns", p.getNs());
   470             attr("datatypeLibrary", p.getDatatypeLibrary());
   471             attr("type", p.getType());
   472             on(p.getAnnotation());
   473             body(p.getValue());
   474             end();
   475             return null;
   476         }
   478         public Void onZeroOrMore(DZeroOrMorePattern p) {
   479             start("zeroOrMore");
   480             on(p.getAnnotation());
   481             unwrapGroup(p.getChild());
   482             end();
   483             return null;
   484         }
   485     }
   487     protected class NameClassXMLPrinterVisitor extends XMLWriter implements NameClassVisitor<Void> {
   488         public Void visitChoice(NameClass nc1, NameClass nc2) {
   489             // TODO: flatten nested choices
   490             start("choice");
   491             nc1.accept(this);
   492             nc2.accept(this);
   493             end();
   494             return null;
   495         }
   497         public Void visitNsName(String ns) {
   498             start("nsName");
   499             attr("ns", ns);
   500             end();
   501             return null;
   502         }
   504         public Void visitNsNameExcept(String ns, NameClass nc) {
   505             start("nsName");
   506             attr("ns", ns);
   507             start("except");
   508             nc.accept(this);
   509             end();
   510             end();
   511             return null;
   512         }
   514         public Void visitAnyName() {
   515             start("anyName");
   516             end();
   517             return null;
   518         }
   520         public Void visitAnyNameExcept(NameClass nc) {
   521             start("anyName");
   522             start("except");
   523             nc.accept(this);
   524             end();
   525             end();
   526             return null;
   527         }
   529         public Void visitName(QName name) {
   530             start("name");
   531             if (!name.getPrefix().equals("")) {
   532                 body(name.getPrefix() + ":");
   533             }
   534             body(name.getLocalPart());
   535             end();
   536             return null;
   537         }
   539         public Void visitNull() {
   540             throw new UnsupportedOperationException("visitNull");
   541         }
   542     }
   544     public static void main(String[] args) throws Exception {
   545         Parseable p;
   547         ErrorHandler eh = new DefaultHandler() {
   548             @Override
   549             public void error(SAXParseException e) throws SAXException {
   550                 throw e;
   551             }
   552         };
   554         // the error handler passed to Parseable will receive parsing errors.
   555         String path = new File(args[0]).toURL().toString();
   556         if (args[0].endsWith(".rng")) {
   557             p = new SAXParseable(new InputSource(path), eh);
   558         } else {
   559             p = new CompactParseable(new InputSource(path), eh);
   560         }
   562         // the error handler passed to CheckingSchemaBuilder will receive additional
   563         // errors found during the RELAX NG restrictions check.
   564         // typically you'd want to pass in the same error handler,
   565         // as there's really no distinction between those two kinds of errors.
   566         SchemaBuilder sb = new CheckingSchemaBuilder(new DSchemaBuilderImpl(), eh);
   567         try {
   568             // run the parser
   569             DGrammarPattern grammar = (DGrammarPattern) p.parse(sb);
   570             OutputStream out = new FileOutputStream(args[1]);
   571             XMLOutputFactory factory = XMLOutputFactory.newInstance();
   572             factory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE);
   573             XMLStreamWriter output = factory.createXMLStreamWriter(out);
   574             DXMLPrinter printer = new DXMLPrinter(output);
   575             printer.printDocument(grammar);
   576             output.close();
   577             out.close();
   578         } catch (BuildException e) {
   579             if (e.getCause() instanceof SAXParseException) {
   580                 SAXParseException se = (SAXParseException) e.getCause();
   581                 System.out.println("("
   582                     + se.getLineNumber()
   583                     + ","
   584                     + se.getColumnNumber()
   585                     + "): "
   586                     + se.getMessage());
   587                 return;
   588             } else
   589                 // I found that Crimson doesn't show the proper stack trace
   590                 // when a RuntimeException happens inside a SchemaBuilder.
   591                 // the following code shows the actual exception that happened.
   592                 if (e.getCause() instanceof SAXException) {
   593                     SAXException se = (SAXException) e.getCause();
   594                     if (se.getException() != null)
   595                         se.getException().printStackTrace();
   596                 }
   597             throw e;
   598         }
   599     }
   600 }

mercurial