001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.bind.v2.runtime.unmarshaller;
038:
039: import javax.xml.namespace.NamespaceContext;
040:
041: import org.xml.sax.SAXException;
042:
043: /**
044: * Walks the XML document structure.
045: *
046: * Implemented by the unmarshaller and called by the API-specific connectors.
047: *
048: * <h2>Event Call Sequence</h2>
049: *
050: * The {@link XmlVisitor} expects the event callbacks in the following order:
051: * <pre>
052: * CALL SEQUENCE := startDocument ELEMENT endDocument
053: * ELEMENT := startPrefixMapping ELEMENT endPrefixMapping
054: * | startElement BODY endElement
055: * BODY := text? (ELEMENT text?)*
056: * </pre>
057: * Note in particular that text events may not be called in a row;
058: * consecutive characters (even those separated by PIs and comments)
059: * must be reported as one event, unlike SAX.
060: *
061: * <p>
062: * All namespace URIs, local names, and prefixes of element and attribute
063: * names must be interned. qnames need not be interned.
064: *
065: *
066: * <h2>Typed PCDATA</h2>
067: * For efficiency, JAXB RI defines a few {@link CharSequence} implementations
068: * that can be used as a parameter to the {@link #text(CharSequence)} method.
069: * For example, see {@link Base64Data}.
070: *
071: * <h2>Error Handling</h2>
072: * The visitor may throw {@link SAXException} to abort the unmarshalling process
073: * in the middle.
074: *
075: * @author Kohsuke Kawaguchi
076: */
077: public interface XmlVisitor {
078: /**
079: * Notifies a start of the document.
080: *
081: * @param locator
082: * This live object returns the location information as the parsing progresses.
083: * must not be null.
084: * @param nsContext
085: * Some broken XML APIs can't iterate all the in-scope namespace bindings,
086: * which makes it impossible to emulate {@link #startPrefixMapping(String, String)} correctly
087: * when unmarshalling a subtree. Connectors that use such an API can
088: * pass in additional {@link NamespaceContext} object that knows about the
089: * in-scope namespace bindings. Otherwise (and normally) it is null.
090: *
091: * <p>
092: * Ideally this object should be immutable and only represent the namespace URI bindings
093: * in the context (those done above the element that JAXB started unmarshalling),
094: * but it can also work even if it changes as the parsing progress (to include
095: * namespaces declared on the current element being parsed.)
096: */
097: void startDocument(LocatorEx locator, NamespaceContext nsContext)
098: throws SAXException;
099:
100: void endDocument() throws SAXException;
101:
102: /**
103: * Notifies a start tag of a new element.
104: *
105: * namespace URIs and local names must be interned.
106: */
107: void startElement(TagName tagName) throws SAXException;
108:
109: void endElement(TagName tagName) throws SAXException;
110:
111: /**
112: * Called before {@link #startElement} event to notify a new namespace binding.
113: */
114: void startPrefixMapping(String prefix, String nsUri)
115: throws SAXException;
116:
117: /**
118: * Called after {@link #endElement} event to notify the end of a binding.
119: */
120: void endPrefixMapping(String prefix) throws SAXException;
121:
122: /**
123: * Text events.
124: *
125: * <p>
126: * The caller should consult {@link TextPredictor} to see
127: * if the unmarshaller is expecting any PCDATA. If the above is returning
128: * false, the caller is OK to skip any text in XML. The net effect is
129: * that we can ignore whitespaces quickly.
130: *
131: * @param pcdata
132: * represents character data. This object can be mutable
133: * (such as {@link StringBuilder}); it only needs to be fixed
134: * while this method is executing.
135: */
136: void text(CharSequence pcdata) throws SAXException;
137:
138: /**
139: * Returns the {@link UnmarshallingContext} at the end of the chain.
140: *
141: * @return
142: * always return the same object, so caching the result is recommended.
143: */
144: UnmarshallingContext getContext();
145:
146: /**
147: * Gets the predictor that can be used for the caller to avoid
148: * calling {@link #text(CharSequence)} unnecessarily.
149: */
150: TextPredictor getPredictor();
151:
152: interface TextPredictor {
153: /**
154: * Returns true if the visitor is expecting a text event as the next event.
155: *
156: * <p>
157: * This is primarily intended to be used for optimization to avoid buffering
158: * characters unnecessarily. If this method returns false and the connector
159: * sees whitespace it can safely skip it.
160: *
161: * <p>
162: * If this method returns true, all the whitespaces are considered significant
163: * and thus need to be reported as a {@link XmlVisitor#text} event. Furthermore,
164: * if the element has no children (like <foo/>), then it has to be reported
165: * an empty {@link XmlVisitor#text} event.
166: */
167: boolean expectText();
168: }
169: }
|