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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 408
b0610cd08440
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

     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             throw (XMLStreamException) e.getCause();
   114         }
   115     }
   117     /**
   118      * Prints XML fragment for the given pattern.
   119      *
   120      * @throws XMLStreamException
   121      */
   122     public void print(DPattern pattern) throws XMLStreamException {
   123         try {
   124             pattern.accept(visitor);
   125         } catch (XMLWriterException e) {
   126             throw (XMLStreamException) e.getCause();
   127         }
   128     }
   130     /**
   131      * Prints XML fragment for the given name class.
   132      *
   133      * @throws XMLStreamException
   134      */
   135     public void print(NameClass nc) throws XMLStreamException {
   136         try {
   137             nc.accept(ncVisitor);
   138         } catch (XMLWriterException e) {
   139             throw (XMLStreamException) e.getCause();
   140         }
   141     }
   143     public void print(Node node) throws XMLStreamException {
   144         domPrinter.print(node);
   145     }
   147     protected class XMLWriterException extends RuntimeException {
   148         protected XMLWriterException(Throwable cause) {
   149             super(cause);
   150         }
   151     }
   153     protected class XMLWriter {
   154         protected void newLine() {
   155             try {
   156                 out.writeCharacters(newLine);
   157             } catch (XMLStreamException e) {
   158                 throw new XMLWriterException(e);
   159             }
   160         }
   162         protected void indent() {
   163             try {
   164                 for (int i = 0; i < indent; i++) {
   165                     out.writeCharacters(indentStep);
   166                 }
   167             } catch (XMLStreamException e) {
   168                 throw new XMLWriterException(e);
   169             }
   170         }
   172         public void startDocument() {
   173             try {
   174                 out.writeStartDocument();
   175             } catch (XMLStreamException e) {
   176                 throw new XMLWriterException(e);
   177             }
   178         }
   180         public void endDocument() {
   181             try {
   182                 out.writeEndDocument();
   183             } catch (XMLStreamException e) {
   184                 throw new XMLWriterException(e);
   185             }
   186         }
   188         public final void start(String element) {
   189             try {
   190                 newLine();
   191                 indent();
   192                 out.writeStartElement(element);
   193                 indent++;
   194                 afterEnd = false;
   195             } catch (XMLStreamException e) {
   196                 throw new XMLWriterException(e);
   197             }
   198         }
   200         public void end() {
   201             try {
   202                 indent--;
   203                 if (afterEnd) {
   204                     newLine();
   205                     indent();
   206                 }
   207                 out.writeEndElement();
   208                 afterEnd = true;
   209             } catch (XMLStreamException e) {
   210                 throw new XMLWriterException(e);
   211             }
   212         }
   214         public void attr(String prefix, String ns, String name, String value) {
   215             try {
   216                 out.writeAttribute(prefix, ns, name, value);
   217             } catch (XMLStreamException e) {
   218                 throw new XMLWriterException(e);
   219             }
   220         }
   222         public void attr(String name, String value) {
   223             try {
   224                 out.writeAttribute(name, value);
   225             } catch (XMLStreamException e) {
   226                 throw new XMLWriterException(e);
   227             }
   228         }
   230         public void ns(String prefix, String uri) {
   231             try {
   232                 out.writeNamespace(prefix, uri);
   233             } catch (XMLStreamException e) {
   234                 throw new XMLWriterException(e);
   235             }
   236         }
   238         public void body(String text) {
   239             try {
   240                 out.writeCharacters(text);
   241                 afterEnd = false;
   242             } catch (XMLStreamException e) {
   243                 throw new XMLWriterException(e);
   244             }
   245         }
   246     }
   248     protected class DXMLPrinterVisitor extends XMLWriter implements DPatternVisitor<Void> {
   249         protected void on(DPattern p) {
   250             p.accept(this);
   251         }
   253         protected void unwrapGroup(DPattern p) {
   254             if (p instanceof DGroupPattern && p.getAnnotation() == DAnnotation.EMPTY) {
   255                 for (DPattern d : (DGroupPattern) p) {
   256                     on(d);
   257                 }
   258             } else {
   259                 on(p);
   260             }
   261         }
   263         protected void unwrapChoice(DPattern p) {
   264             if (p instanceof DChoicePattern && p.getAnnotation() == DAnnotation.EMPTY) {
   265                 for (DPattern d : (DChoicePattern) p) {
   266                     on(d);
   267                 }
   268             } else {
   269                 on(p);
   270             }
   271         }
   273         protected void on(NameClass nc) {
   274             if (nc instanceof SimpleNameClass) {
   275                 QName qname = ((SimpleNameClass) nc).name;
   276                 String name = qname.getLocalPart();
   277                 if (!qname.getPrefix().equals("")) name = qname.getPrefix() + ":";
   278                 attr("name", name);
   279             } else {
   280                 nc.accept(ncVisitor);
   281             }
   282         }
   284         protected void on(DAnnotation ann) {
   285             if (ann == DAnnotation.EMPTY) return;
   286             for (DAnnotation.Attribute attr : ann.getAttributes().values()) {
   287                 attr(attr.getPrefix(), attr.getNs(), attr.getLocalName(), attr.getValue());
   288             }
   289             for (Element elem : ann.getChildren()) {
   290                 try {
   291                     newLine();
   292                     indent();
   293                     print(elem);
   294                 }
   295                 catch (XMLStreamException e) {
   296                     throw new XMLWriterException(e);
   297                 }
   298             }
   299         }
   301         public Void onAttribute(DAttributePattern p) {
   302             start("attribute");
   303             on(p.getName());
   304             on(p.getAnnotation());
   305             DPattern child = p.getChild();
   306             // do not print default value
   307             if (!(child instanceof DTextPattern)) {
   308                 on(p.getChild());
   309             }
   310             end();
   311             return null;
   312         }
   314         public Void onChoice(DChoicePattern p) {
   315             start("choice");
   316             on(p.getAnnotation());
   317             for (DPattern d : p) {
   318                 on(d);
   319             }
   320             end();
   321             return null;
   322         }
   324         public Void onData(DDataPattern p) {
   325             List<DDataPattern.Param> params = p.getParams();
   326             DPattern except = p.getExcept();
   327             start("data");
   328             attr("datatypeLibrary", p.getDatatypeLibrary());
   329             attr("type", p.getType());
   330             on(p.getAnnotation());
   331             for (DDataPattern.Param param : params) {
   332                 start("param");
   333                 attr("ns", param.getNs());
   334                 attr("name", param.getName());
   335                 body(param.getValue());
   336                 end();
   337             }
   338             if (except != null) {
   339                 start("except");
   340                 unwrapChoice(except);
   341                 end();
   342             }
   343             end();
   344             return null;
   345         }
   347         public Void onElement(DElementPattern p) {
   348             start("element");
   349             on(p.getName());
   350             on(p.getAnnotation());
   351             unwrapGroup(p.getChild());
   352             end();
   353             return null;
   354         }
   356         public Void onEmpty(DEmptyPattern p) {
   357             start("empty");
   358             on(p.getAnnotation());
   359             end();
   360             return null;
   361         }
   363         public Void onGrammar(DGrammarPattern p) {
   364             start("grammar");
   365             ns(null, WellKnownNamespaces.RELAX_NG);
   366             on(p.getAnnotation());
   367             start("start");
   368             on(p.getStart());
   369             end();
   370             for (DDefine d : p) {
   371                 start("define");
   372                 attr("name", d.getName());
   373                 on(d.getAnnotation());
   374                 unwrapGroup(d.getPattern());
   375                 end();
   376             }
   377             end();
   378             return null;
   379         }
   381         public Void onGroup(DGroupPattern p) {
   382             start("group");
   383             on(p.getAnnotation());
   384             for (DPattern d : p) {
   385                 on(d);
   386             }
   387             end();
   388             return null;
   389         }
   391         public Void onInterleave(DInterleavePattern p) {
   392             start("interleave");
   393             on(p.getAnnotation());
   394             for (DPattern d : p) {
   395                 on(d);
   396             }
   397             end();
   398             return null;
   399         }
   401         public Void onList(DListPattern p) {
   402             start("list");
   403             on(p.getAnnotation());
   404             unwrapGroup(p.getChild());
   405             end();
   406             return null;
   407         }
   409         public Void onMixed(DMixedPattern p) {
   410             start("mixed");
   411             on(p.getAnnotation());
   412             unwrapGroup(p.getChild());
   413             end();
   414             return null;
   415         }
   417         public Void onNotAllowed(DNotAllowedPattern p) {
   418             start("notAllowed");
   419             on(p.getAnnotation());
   420             end();
   421             return null;
   422         }
   424         public Void onOneOrMore(DOneOrMorePattern p) {
   425             start("oneOrMore");
   426             on(p.getAnnotation());
   427             unwrapGroup(p.getChild());
   428             end();
   429             return null;
   430         }
   432         public Void onOptional(DOptionalPattern p) {
   433             start("optional");
   434             on(p.getAnnotation());
   435             unwrapGroup(p.getChild());
   436             end();
   437             return null;
   438         }
   440         public Void onRef(DRefPattern p) {
   441             start("ref");
   442             attr("name", p.getName());
   443             on(p.getAnnotation());
   444             end();
   445             return null;
   446         }
   448         public Void onText(DTextPattern p) {
   449             start("text");
   450             on(p.getAnnotation());
   451             end();
   452             return null;
   453         }
   455         public Void onValue(DValuePattern p) {
   456             start("value");
   457             if (!p.getNs().equals("")) attr("ns", p.getNs());
   458             attr("datatypeLibrary", p.getDatatypeLibrary());
   459             attr("type", p.getType());
   460             on(p.getAnnotation());
   461             body(p.getValue());
   462             end();
   463             return null;
   464         }
   466         public Void onZeroOrMore(DZeroOrMorePattern p) {
   467             start("zeroOrMore");
   468             on(p.getAnnotation());
   469             unwrapGroup(p.getChild());
   470             end();
   471             return null;
   472         }
   473     }
   475     protected class NameClassXMLPrinterVisitor extends XMLWriter implements NameClassVisitor<Void> {
   476         public Void visitChoice(NameClass nc1, NameClass nc2) {
   477             // TODO: flatten nested choices
   478             start("choice");
   479             nc1.accept(this);
   480             nc2.accept(this);
   481             end();
   482             return null;
   483         }
   485         public Void visitNsName(String ns) {
   486             start("nsName");
   487             attr("ns", ns);
   488             end();
   489             return null;
   490         }
   492         public Void visitNsNameExcept(String ns, NameClass nc) {
   493             start("nsName");
   494             attr("ns", ns);
   495             start("except");
   496             nc.accept(this);
   497             end();
   498             end();
   499             return null;
   500         }
   502         public Void visitAnyName() {
   503             start("anyName");
   504             end();
   505             return null;
   506         }
   508         public Void visitAnyNameExcept(NameClass nc) {
   509             start("anyName");
   510             start("except");
   511             nc.accept(this);
   512             end();
   513             end();
   514             return null;
   515         }
   517         public Void visitName(QName name) {
   518             start("name");
   519             if (!name.getPrefix().equals("")) {
   520                 body(name.getPrefix() + ":");
   521             }
   522             body(name.getLocalPart());
   523             end();
   524             return null;
   525         }
   527         public Void visitNull() {
   528             throw new UnsupportedOperationException("visitNull");
   529         }
   530     }
   532     public static void main(String[] args) throws Exception {
   533         Parseable p;
   535         ErrorHandler eh = new DefaultHandler() {
   536             @Override
   537             public void error(SAXParseException e) throws SAXException {
   538                 throw e;
   539             }
   540         };
   542         // the error handler passed to Parseable will receive parsing errors.
   543         String path = new File(args[0]).toURL().toString();
   544         if (args[0].endsWith(".rng")) {
   545             p = new SAXParseable(new InputSource(path), eh);
   546         } else {
   547             p = new CompactParseable(new InputSource(path), eh);
   548         }
   550         // the error handler passed to CheckingSchemaBuilder will receive additional
   551         // errors found during the RELAX NG restrictions check.
   552         // typically you'd want to pass in the same error handler,
   553         // as there's really no distinction between those two kinds of errors.
   554         SchemaBuilder sb = new CheckingSchemaBuilder(new DSchemaBuilderImpl(), eh);
   555         try {
   556             // run the parser
   557             DGrammarPattern grammar = (DGrammarPattern) p.parse(sb);
   558             OutputStream out = new FileOutputStream(args[1]);
   559             XMLOutputFactory factory = XMLOutputFactory.newInstance();
   560             factory.setProperty("javax.xml.stream.isRepairingNamespaces", Boolean.TRUE);
   561             XMLStreamWriter output = factory.createXMLStreamWriter(out);
   562             DXMLPrinter printer = new DXMLPrinter(output);
   563             printer.printDocument(grammar);
   564             output.close();
   565             out.close();
   566         } catch (BuildException e) {
   567             if (e.getCause() instanceof SAXParseException) {
   568                 SAXParseException se = (SAXParseException) e.getCause();
   569                 System.out.println("("
   570                     + se.getLineNumber()
   571                     + ","
   572                     + se.getColumnNumber()
   573                     + "): "
   574                     + se.getMessage());
   575                 return;
   576             } else
   577                 // I found that Crimson doesn't show the proper stack trace
   578                 // when a RuntimeException happens inside a SchemaBuilder.
   579                 // the following code shows the actual exception that happened.
   580                 if (e.getCause() instanceof SAXException) {
   581                     SAXException se = (SAXException) e.getCause();
   582                     if (se.getException() != null)
   583                         se.getException().printStackTrace();
   584                 }
   585             throw e;
   586         }
   587     }
   588 }

mercurial