1 /*
2 * Copyright (c) 1997, 2013, 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
33 import org.xml.sax.Attributes;
34 import org.xml.sax.ContentHandler;
35 import org.xml.sax.Locator;
36 import org.xml.sax.SAXException;
37 import org.xml.sax.SAXParseException;
38
39 /**
40 * Runtime Engine for RELAXNGCC execution.
41 *
42 * This class has the following functionalities:
43 *
44 * <ol>
45 * <li>Managing a stack of NGCCHandler objects and
46 * switching between them appropriately.
47 *
48 * <li>Keep track of all Attributes.
49 *
50 * <li>manage mapping between namespace URIs and prefixes.
51 *
52 * <li>TODO: provide support for interleaving.
53 * <p><b>
54 * Auto-generated, do not edit.
55 * </b></p>
56 * @version $Id: NGCCRuntime.java,v 1.15 2002/09/29 02:55:48 okajima Exp $
57 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
58 */
59 public class NGCCRuntime implements ContentHandler, NGCCEventSource {
60
61 public NGCCRuntime() {
62 reset();
63 }
64
65 /**
66 * Sets the root handler, which will be used to parse the
67 * root element.
68 * <p>
69 * This method can be called right after the object is created
70 * or the reset method is called. You can't replace the root
71 * handler while parsing is in progress.
72 * <p>
73 * Usually a generated class that corresponds to the <start>
74 * pattern will be used as the root handler, but any NGCCHandler
75 * can be a root handler.
76 *
77 * @exception IllegalStateException
78 * If this method is called but it doesn't satisfy the
79 * pre-condition stated above.
80 */
81 public void setRootHandler( NGCCHandler rootHandler ) {
82 if(currentHandler!=null)
83 throw new IllegalStateException();
84 currentHandler = rootHandler;
85 }
86
87
88 /**
89 * Cleans up all the data structure so that the object can be reused later.
90 * Normally, applications do not need to call this method directly,
91 *
92 * as the runtime resets itself after the endDocument method.
93 */
148 private NGCCEventReceiver currentHandler;
149
150 public int replace( NGCCEventReceiver o, NGCCEventReceiver n ) {
151 if(o!=currentHandler)
152 throw new IllegalStateException(); // bug of RelaxNGCC
153 currentHandler = n;
154
155 return 0; // we only have one thread.
156 }
157
158 /**
159 * Processes buffered text.
160 *
161 * This method will be called by the start/endElement event to process
162 * buffered text as a text event.
163 *
164 * <p>
165 * Whitespace handling is a tricky business. Consider the following
166 * schema fragment:
167 *
168 * <pre>{@code
169 * <element name="foo">
170 * <choice>
171 * <element name="bar"><empty/></element>
172 * <text/>
173 * </choice>
174 * </element>
175 * }</pre>
176 *
177 * Assume we hit the following instance:
178 * <pre>{@code
179 * <foo> <bar/></foo>
180 * }</pre>
181 *
182 * Then this first space needs to be ignored (for otherwise, we will
183 * end up treating this space as the match to <text/> and won't
184 * be able to process <bar>.)
185 *
186 * Now assume the following instance:
187 * <pre>{@code
188 * <foo/>
189 * }</pre>
190 *
191 * This time, we need to treat this empty string as a text, for
192 * otherwise we won't be able to accept this instance.
193 *
194 * <p>
195 * This is very difficult to solve in general, but one seemingly
196 * easy solution is to use the type of next event. If a text is
197 * followed by a start tag, it follows from the constraint on
198 * RELAX NG that that text must be either whitespaces or a match
199 * to <text/>.
200 *
201 * <p>
202 * On the contrary, if a text is followed by a end tag, then it
203 * cannot be whitespace unless the content model can accept empty,
204 * in which case sending a text event will be harmlessly ignored
205 * by the NGCCHandler.
206 *
207 * <p>
208 * Thus this method take one parameter, which controls the
209 * behavior of this method.
466 );
467
468 redirect.startElement(uri,local,qname,currentAtts);
469 redirectionDepth=1;
470 }
471
472 //
473 //
474 // validation context implementation
475 //
476 //
477 /** in-scope namespace mapping.
478 * namespaces[2n ] := prefix
479 * namespaces[2n+1] := namespace URI */
480 private final ArrayList namespaces = new ArrayList();
481 /**
482 * Index on the namespaces array, which points to
483 * the top of the effective bindings. Because of the
484 * timing difference between the startPrefixMapping method
485 * and the execution of the corresponding actions,
486 * this value can be different from {@code namespaces.size()}.
487 * <p>
488 * For example, consider the following schema:
489 * <pre>{@code
490 * <oneOrMore>
491 * <element name="foo"><empty/></element>
492 * </oneOrMore>
493 * code fragment X
494 * <element name="bob"/>
495 * }</pre>
496 * Code fragment X is executed after we see a startElement event,
497 * but at this time the namespaces variable already include new
498 * namespace bindings declared on "bob".
499 */
500 private int nsEffectivePtr=0;
501
502 /**
503 * Stack to preserve old nsEffectivePtr values.
504 */
505 private final Stack nsEffectiveStack = new Stack();
506
507 public String resolveNamespacePrefix( String prefix ) {
508 for( int i = nsEffectivePtr-2; i>=0; i-=2 )
509 if( namespaces.get(i).equals(prefix) )
510 return (String)namespaces.get(i+1);
511
512 // no binding was found.
513 if(prefix.equals("")) return ""; // return the default no-namespace
514 if(prefix.equals("xml")) // pre-defined xml prefix
515 return "http://www.w3.org/XML/1998/namespace";
|
1 /*
2 * Copyright (c) 1997, 2015, 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
33 import org.xml.sax.Attributes;
34 import org.xml.sax.ContentHandler;
35 import org.xml.sax.Locator;
36 import org.xml.sax.SAXException;
37 import org.xml.sax.SAXParseException;
38
39 /**
40 * Runtime Engine for RELAXNGCC execution.
41 *
42 * This class has the following functionalities:
43 *
44 * <ol>
45 * <li>Managing a stack of NGCCHandler objects and
46 * switching between them appropriately.
47 *
48 * <li>Keep track of all Attributes.
49 *
50 * <li>manage mapping between namespace URIs and prefixes.
51 *
52 * <li>TODO: provide support for interleaving.
53 * </ol>
54 * <p><b>
55 * Auto-generated, do not edit.
56 * </b></p>
57 * @version $Id: NGCCRuntime.java,v 1.15 2002/09/29 02:55:48 okajima Exp $
58 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
59 */
60 public class NGCCRuntime implements ContentHandler, NGCCEventSource {
61
62 public NGCCRuntime() {
63 reset();
64 }
65
66 /**
67 * Sets the root handler, which will be used to parse the
68 * root element.
69 * <p>
70 * This method can be called right after the object is created
71 * or the reset method is called. You can't replace the root
72 * handler while parsing is in progress.
73 * <p>
74 * Usually a generated class that corresponds to the {@code <start>}
75 * pattern will be used as the root handler, but any NGCCHandler
76 * can be a root handler.
77 *
78 * @exception IllegalStateException
79 * If this method is called but it doesn't satisfy the
80 * pre-condition stated above.
81 */
82 public void setRootHandler( NGCCHandler rootHandler ) {
83 if(currentHandler!=null)
84 throw new IllegalStateException();
85 currentHandler = rootHandler;
86 }
87
88
89 /**
90 * Cleans up all the data structure so that the object can be reused later.
91 * Normally, applications do not need to call this method directly,
92 *
93 * as the runtime resets itself after the endDocument method.
94 */
149 private NGCCEventReceiver currentHandler;
150
151 public int replace( NGCCEventReceiver o, NGCCEventReceiver n ) {
152 if(o!=currentHandler)
153 throw new IllegalStateException(); // bug of RelaxNGCC
154 currentHandler = n;
155
156 return 0; // we only have one thread.
157 }
158
159 /**
160 * Processes buffered text.
161 *
162 * This method will be called by the start/endElement event to process
163 * buffered text as a text event.
164 *
165 * <p>
166 * Whitespace handling is a tricky business. Consider the following
167 * schema fragment:
168 *
169 * <xmp>
170 * <element name="foo">
171 * <choice>
172 * <element name="bar"><empty/></element>
173 * <text/>
174 * </choice>
175 * </element>
176 * </xmp>
177 *
178 * Assume we hit the following instance:
179 * <xmp>
180 * <foo> <bar/></foo>
181 * </xmp>
182 *
183 * Then this first space needs to be ignored (for otherwise, we will
184 * end up treating this space as the match to <text/> and won't
185 * be able to process <bar>.)
186 *
187 * Now assume the following instance:
188 * <xmp>
189 * <foo/>
190 * </xmp>
191 *
192 * This time, we need to treat this empty string as a text, for
193 * otherwise we won't be able to accept this instance.
194 *
195 * <p>
196 * This is very difficult to solve in general, but one seemingly
197 * easy solution is to use the type of next event. If a text is
198 * followed by a start tag, it follows from the constraint on
199 * RELAX NG that that text must be either whitespaces or a match
200 * to <text/>.
201 *
202 * <p>
203 * On the contrary, if a text is followed by a end tag, then it
204 * cannot be whitespace unless the content model can accept empty,
205 * in which case sending a text event will be harmlessly ignored
206 * by the NGCCHandler.
207 *
208 * <p>
209 * Thus this method take one parameter, which controls the
210 * behavior of this method.
467 );
468
469 redirect.startElement(uri,local,qname,currentAtts);
470 redirectionDepth=1;
471 }
472
473 //
474 //
475 // validation context implementation
476 //
477 //
478 /** in-scope namespace mapping.
479 * namespaces[2n ] := prefix
480 * namespaces[2n+1] := namespace URI */
481 private final ArrayList namespaces = new ArrayList();
482 /**
483 * Index on the namespaces array, which points to
484 * the top of the effective bindings. Because of the
485 * timing difference between the startPrefixMapping method
486 * and the execution of the corresponding actions,
487 * this value can be different from <code>namespaces.size()</code>.
488 * <p>
489 * For example, consider the following schema:
490 * <pre><xmp>
491 * <oneOrMore>
492 * <element name="foo"><empty/></element>
493 * </oneOrMore>
494 * code fragment X
495 * <element name="bob"/>
496 * </xmp></pre>
497 * Code fragment X is executed after we see a startElement event,
498 * but at this time the namespaces variable already include new
499 * namespace bindings declared on "bob".
500 */
501 private int nsEffectivePtr=0;
502
503 /**
504 * Stack to preserve old nsEffectivePtr values.
505 */
506 private final Stack nsEffectiveStack = new Stack();
507
508 public String resolveNamespacePrefix( String prefix ) {
509 for( int i = nsEffectivePtr-2; i>=0; i-=2 )
510 if( namespaces.get(i).equals(prefix) )
511 return (String)namespaces.get(i+1);
512
513 // no binding was found.
514 if(prefix.equals("")) return ""; // return the default no-namespace
515 if(prefix.equals("xml")) // pre-defined xml prefix
516 return "http://www.w3.org/XML/1998/namespace";
|