Tue, 06 Mar 2012 16:09:35 -0800
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 }