aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.bind.v2.runtime.unmarshaller; aoqi@0: aoqi@0: import javax.xml.namespace.NamespaceContext; aoqi@0: aoqi@0: import org.xml.sax.SAXException; aoqi@0: aoqi@0: /** aoqi@0: * Walks the XML document structure. aoqi@0: * aoqi@0: * Implemented by the unmarshaller and called by the API-specific connectors. aoqi@0: * aoqi@0: *

Event Call Sequence

aoqi@0: * aoqi@0: * The {@link XmlVisitor} expects the event callbacks in the following order: aoqi@0: *
aoqi@0:  * CALL SEQUENCE := startDocument ELEMENT endDocument
aoqi@0:  * ELEMENT       := startPrefixMapping ELEMENT endPrefixMapping
aoqi@0:  *               |  startElement BODY endElement
aoqi@0:  * BODY          := text? (ELEMENT text?)*
aoqi@0:  * 
aoqi@0: * Note in particular that text events may not be called in a row; aoqi@0: * consecutive characters (even those separated by PIs and comments) aoqi@0: * must be reported as one event, unlike SAX. aoqi@0: * aoqi@0: *

aoqi@0: * All namespace URIs, local names, and prefixes of element and attribute aoqi@0: * names must be interned. qnames need not be interned. aoqi@0: * aoqi@0: * aoqi@0: *

Typed PCDATA

aoqi@0: * For efficiency, JAXB RI defines a few {@link CharSequence} implementations aoqi@0: * that can be used as a parameter to the {@link #text(CharSequence)} method. aoqi@0: * For example, see {@link Base64Data}. aoqi@0: * aoqi@0: *

Error Handling

aoqi@0: * The visitor may throw {@link SAXException} to abort the unmarshalling process aoqi@0: * in the middle. aoqi@0: * aoqi@0: * @author Kohsuke Kawaguchi aoqi@0: */ aoqi@0: public interface XmlVisitor { aoqi@0: /** aoqi@0: * Notifies a start of the document. aoqi@0: * aoqi@0: * @param locator aoqi@0: * This live object returns the location information as the parsing progresses. aoqi@0: * must not be null. aoqi@0: * @param nsContext aoqi@0: * Some broken XML APIs can't iterate all the in-scope namespace bindings, aoqi@0: * which makes it impossible to emulate {@link #startPrefixMapping(String, String)} correctly aoqi@0: * when unmarshalling a subtree. Connectors that use such an API can aoqi@0: * pass in additional {@link NamespaceContext} object that knows about the aoqi@0: * in-scope namespace bindings. Otherwise (and normally) it is null. aoqi@0: * aoqi@0: *

aoqi@0: * Ideally this object should be immutable and only represent the namespace URI bindings aoqi@0: * in the context (those done above the element that JAXB started unmarshalling), aoqi@0: * but it can also work even if it changes as the parsing progress (to include aoqi@0: * namespaces declared on the current element being parsed.) aoqi@0: */ aoqi@0: void startDocument(LocatorEx locator, NamespaceContext nsContext) throws SAXException; aoqi@0: void endDocument() throws SAXException; aoqi@0: aoqi@0: /** aoqi@0: * Notifies a start tag of a new element. aoqi@0: * aoqi@0: * namespace URIs and local names must be interned. aoqi@0: */ aoqi@0: void startElement(TagName tagName) throws SAXException; aoqi@0: void endElement(TagName tagName) throws SAXException; aoqi@0: aoqi@0: /** aoqi@0: * Called before {@link #startElement} event to notify a new namespace binding. aoqi@0: */ aoqi@0: void startPrefixMapping( String prefix, String nsUri ) throws SAXException; aoqi@0: /** aoqi@0: * Called after {@link #endElement} event to notify the end of a binding. aoqi@0: */ aoqi@0: void endPrefixMapping( String prefix ) throws SAXException; aoqi@0: aoqi@0: /** aoqi@0: * Text events. aoqi@0: * aoqi@0: *

aoqi@0: * The caller should consult {@link TextPredictor} to see aoqi@0: * if the unmarshaller is expecting any PCDATA. If the above is returning aoqi@0: * false, the caller is OK to skip any text in XML. The net effect is aoqi@0: * that we can ignore whitespaces quickly. aoqi@0: * aoqi@0: * @param pcdata aoqi@0: * represents character data. This object can be mutable aoqi@0: * (such as {@link StringBuilder}); it only needs to be fixed aoqi@0: * while this method is executing. aoqi@0: */ aoqi@0: void text( CharSequence pcdata ) throws SAXException; aoqi@0: aoqi@0: /** aoqi@0: * Returns the {@link UnmarshallingContext} at the end of the chain. aoqi@0: * aoqi@0: * @return aoqi@0: * always return the same object, so caching the result is recommended. aoqi@0: */ aoqi@0: UnmarshallingContext getContext(); aoqi@0: aoqi@0: /** aoqi@0: * Gets the predictor that can be used for the caller to avoid aoqi@0: * calling {@link #text(CharSequence)} unnecessarily. aoqi@0: */ aoqi@0: TextPredictor getPredictor(); aoqi@0: aoqi@0: interface TextPredictor { aoqi@0: /** aoqi@0: * Returns true if the visitor is expecting a text event as the next event. aoqi@0: * aoqi@0: *

aoqi@0: * This is primarily intended to be used for optimization to avoid buffering aoqi@0: * characters unnecessarily. If this method returns false and the connector aoqi@0: * sees whitespace it can safely skip it. aoqi@0: * aoqi@0: *

aoqi@0: * If this method returns true, all the whitespaces are considered significant aoqi@0: * and thus need to be reported as a {@link XmlVisitor#text} event. Furthermore, aoqi@0: * if the element has no children (like <foo/>), then it has to be reported aoqi@0: * an empty {@link XmlVisitor#text} event. aoqi@0: */ aoqi@0: boolean expectText(); aoqi@0: } aoqi@0: }