Package org.apache.axiom.om.impl.common.serializer.pull

Source Code of org.apache.axiom.om.impl.common.serializer.pull.Navigator

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.axiom.om.impl.common.serializer.pull;

import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.activation.DataHandler;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.axiom.ext.stax.CharacterDataReader;
import org.apache.axiom.ext.stax.DTDReader;
import org.apache.axiom.ext.stax.datahandler.DataHandlerProvider;
import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMComment;
import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMDataSource;
import org.apache.axiom.om.OMDocType;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMEntityReference;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMProcessingInstruction;
import org.apache.axiom.om.OMSerializable;
import org.apache.axiom.om.OMSourcedElement;
import org.apache.axiom.om.OMText;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.builder.StAXBuilder;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.common.IContainer;
import org.apache.axiom.om.impl.common.OMDataSourceUtil;
import org.apache.axiom.util.namespace.MapBasedNamespaceContext;
import org.apache.axiom.util.stax.XMLEventUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* {@link PullSerializerState} implementation that generates events from nodes in the OM tree.
*/
final class Navigator extends PullSerializerState
    implements DataHandlerReader, CharacterDataReader, DTDReader, XMLStreamConstants {
   
    private static final Log log = LogFactory.getLog(Navigator.class);
   
    private final PullSerializer serializer;
   
    /**
     * The current node, corresponding to the current event. It is <code>null</code> if the root
     * node is an {@link OMElement} and the current event is
     * {@link XMLStreamConstants#START_DOCUMENT} or {@link XMLStreamConstants#END_DOCUMENT}.
     */
    private OMSerializable node;

    /**
     * If the current node is an {@link OMContainer}, then this flag indicates whether the current
     * event is the start event ({@link XMLStreamConstants#START_DOCUMENT} or
     * {@link XMLStreamConstants#START_ELEMENT}) or the end event
     * ({@link XMLStreamConstants#END_DOCUMENT} or {@link XMLStreamConstants#END_ELEMENT}) for that
     * node. In the latter case, we have already visited the node before, hence the name of the
     * attribute.
     */
    private boolean visited;

    /**
     * The root node, i.e. the node from which the {@link XMLStreamReader} has been requested.
     */
    private final OMContainer rootNode;

    /** Field currentEvent Default set to START_DOCUMENT */
    private int currentEvent;

    /**
     * Specifies whether the original document content is cached (i.e. whether the object model is
     * built) or can be consumed.
     */
    private final boolean cache;
   
    /**
     * Specifies whether additional namespace declarations should be generated to preserve the
     * namespace context. See {@link OMElement#getXMLStreamReader(boolean, boolean)} for more
     * information about the meaning of this attribute.
     */
    private final boolean preserveNamespaceContext;
   
    // Cache attributes and namespaces. This avoids creating a new Iterator for every call
    // to getAttributeXXX and getNamespaceXXX. A value of -1 indicates that the
    // attributes or namespaces for the current element have not been loaded yet. The
    // two arrays are resized on demand.
    private int attributeCount = -1;
    private OMAttribute[] attributes = new OMAttribute[16];
    private int namespaceCount = -1;
    private OMNamespace[] namespaces = new OMNamespace[16];
   
    /**
     * The data source exposed by {@link #getDataSource()}.
     */
    private OMDataSource ds;
   
    /**
     * Constructor.
     *
     * @param serializer
     * @param builder
     * @param startNode
     * @param cache
     * @param preserveNamespaceContext
     */
    Navigator(PullSerializer serializer, OMContainer startNode,
                            boolean cache, boolean preserveNamespaceContext) {
        this.serializer = serializer;
        this.rootNode = startNode;
        this.cache = cache;
        this.preserveNamespaceContext = preserveNamespaceContext;

        // If the start node is a document it become the current node. If the start node
        // is an element, then there is no current node, because there is no node
        // corresponding to the current event (START_DOCUMENT).
        if (startNode instanceof OMDocument) {
            node = startNode;
        }
        currentEvent = START_DOCUMENT;
    }

    DTDReader getDTDReader() {
        return this;
    }

    DataHandlerReader getDataHandlerReader() {
        return this;
    }

    CharacterDataReader getCharacterDataReader() {
        return this;
    }

    String getPrefix() {
        if ((currentEvent == START_ELEMENT)
                || (currentEvent == END_ELEMENT)) {
            return ((OMElement)node).getPrefix();
        } else {
            throw new IllegalStateException();
        }
    }

    String getNamespaceURI() {
        if ((currentEvent == START_ELEMENT)
                || (currentEvent == END_ELEMENT)) {
            return ((OMElement)node).getNamespaceURI();
        } else {
            throw new IllegalStateException();
        }
    }

    String getLocalName() {
        switch (currentEvent) {
            case START_ELEMENT:
            case END_ELEMENT:
                return ((OMElement)node).getLocalName();
            case ENTITY_REFERENCE:
                return ((OMEntityReference)node).getName();
            default:
                throw new IllegalStateException();
        }
    }

    QName getName() {
        if ((currentEvent == START_ELEMENT)
                || (currentEvent == END_ELEMENT)) {
            // START quick & dirty hack
            if (node instanceof OMSourcedElement) {
                // TODO: Need to force expansion to solve an issue in Axis2 where the returned QName is incorrect.
                //       Note that in previous versions of Navigator, the sourced element was always expanded
                //       at this point (because Navigator was looking 2 nodes ahead).
                ((OMElement)node).getFirstOMChild();
            }
            // END quick & dirty hack
            return ((OMElement)node).getQName();
        } else {
            throw new IllegalStateException();
        }
    }

    int getTextLength() {
        return getTextFromNode().length();
    }

    int getTextStart() {
        switch (currentEvent) {
            case CHARACTERS:
            case CDATA:
            case COMMENT:
            case SPACE:
                // getTextCharacters always returns a new char array and the start
                // index is therefore always 0
                return 0;
            default:
                // getTextStart() is not allowed for DTD and ENTITY_REFERENCE events; see
                // the table in the Javadoc of XMLStreamReader
                throw new IllegalStateException();
        }
    }

    int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
            throws XMLStreamException {
        String text = getTextFromNode();
        int copied = Math.min(length, text.length()-sourceStart);
        text.getChars(sourceStart, sourceStart + copied, target, targetStart);
        return copied;
    }

    char[] getTextCharacters() {
        return getTextFromNode().toCharArray();
    }

    String getText() {
        // For DTD and ENTITY_REFERENCE events, only getText() is allowed, but not getTextCharacters() etc.
        // (see the table in the Javadoc of XMLStreamReader); therefore we handle these event here,
        // and the other ones in getTextFromNode().
        switch (currentEvent) {
            case DTD:
                String internalSubset = ((OMDocType)node).getInternalSubset();
                // Woodstox returns the empty string if there is no internal subset
                return internalSubset != null ? internalSubset : "";
            case ENTITY_REFERENCE:
                return ((OMEntityReference)node).getReplacementText();
            default:
                return getTextFromNode();
        }
    }
   
    /**
     * Get the text for the current node. This methods applies to events for which all
     * <code>getText</code> methods are valid. This excludes {@link XMLStreamConstants#DTD} events
     * for which only {@link #getText()} is valid.
     *
     * @return the text for the current node
     */
    private String getTextFromNode() {
        switch (currentEvent) {
            case CHARACTERS:
            case CDATA:
            case SPACE:
                return ((OMText)node).getText();
            case COMMENT:
                return ((OMComment)node).getValue();
            default:
                throw new IllegalStateException();
        }
    }

    public void writeTextTo(Writer writer) throws XMLStreamException, IOException {
        switch (currentEvent) {
            case CHARACTERS:
            case CDATA:
            case SPACE:
                OMText text = (OMText)node;
                if (text.isCharacters()) {
                    writer.write(text.getTextCharacters());
                } else {
                    // TODO: we should cover the binary case in an optimized way
                    writer.write(text.getText());
                }
                break;
            case COMMENT:
                writer.write(((OMComment)node).getValue());
                break;
            default:
                throw new IllegalStateException();
        }
    }

    int getEventType() {
        return currentEvent;
    }

    private void loadAttributes() {
        if (attributeCount == -1) {
            attributeCount = 0;
            for (Iterator it = ((OMElement)node).getAllAttributes(); it.hasNext(); ) {
                OMAttribute attr = (OMAttribute)it.next();
                if (attributeCount == attributes.length) {
                    OMAttribute[] newAttributes = new OMAttribute[attributes.length*2];
                    System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
                    attributes = newAttributes;
                }
                attributes[attributeCount] = attr;
                attributeCount++;
            }
        }
    }
   
    private OMAttribute getAttribute(int index) {
        loadAttributes();
        return attributes[index];
    }
   
    private void loadNamespaces() {
        if (namespaceCount == -1) {
            namespaceCount = 0;
            for (Iterator it = ((OMElement)node).getAllDeclaredNamespaces(); it.hasNext(); ) {
                addNamespace((OMNamespace)it.next());
            }
            if (preserveNamespaceContext && node == rootNode) {
                OMElement element = (OMElement)node;
                while (true) {
                    OMContainer container = element.getParent();
                    if (container instanceof OMElement) {
                        element = (OMElement)container;
                        decl: for (Iterator it = element.getAllDeclaredNamespaces(); it.hasNext(); ) {
                            OMNamespace ns = (OMNamespace)it.next();
                            String prefix = ns.getPrefix();
                            for (int i=0; i<namespaceCount; i++) {
                                if (namespaces[i].getPrefix().equals(prefix)) {
                                    continue decl;
                                }
                            }
                            addNamespace(ns);
                        }
                    } else {
                        break;
                    }
                }
            }
        }
    }
   
    private OMNamespace getNamespace(int index) {
        loadNamespaces();
        return namespaces[index];
    }
   
    private void addNamespace(OMNamespace ns) {
        // TODO: verify if this check is actually still necessary
        // Axiom internally creates an OMNamespace instance for the "xml" prefix, even
        // if it is not declared explicitly. Filter this instance out.
        if (!"xml".equals(ns.getPrefix())) {
            if (namespaceCount == namespaces.length) {
                OMNamespace[] newNamespaces = new OMNamespace[namespaces.length*2];
                System.arraycopy(namespaces, 0, newNamespaces, 0, namespaces.length);
                namespaces = newNamespaces;
            }
            namespaces[namespaceCount] = ns;
            namespaceCount++;
        }
    }
   
    String getNamespaceURI(int i) {
        if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
            return getNamespace(i).getNamespaceURI();
        } else {
            throw new IllegalStateException();
        }
    }

    String getNamespacePrefix(int i) {
        if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
            String prefix = getNamespace(i).getPrefix();
            return prefix.length() == 0 ? null : prefix;
        } else {
            throw new IllegalStateException();
        }
    }

    int getNamespaceCount() {
        if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {
            loadNamespaces();
            return namespaceCount;
        } else {
            throw new IllegalStateException();
        }
    }

    boolean isAttributeSpecified(int i) {
        if (currentEvent == START_ELEMENT) {
            // The Axiom object model doesn't store this information,
            // but returning true is a reasonable default.
            return true;
        } else {
            throw new IllegalStateException(
                    "attribute type accessed in illegal event!");
        }
    }

    String getAttributeValue(int i) {
        if (currentEvent == START_ELEMENT) {
            return getAttribute(i).getAttributeValue();
        } else {
            throw new IllegalStateException(
                    "attribute type accessed in illegal event!");
        }
    }

    String getAttributeType(int i) {
        if (currentEvent == START_ELEMENT) {
            return getAttribute(i).getAttributeType();
        } else {
            throw new IllegalStateException(
                    "attribute type accessed in illegal event!");
        }
    }

    String getAttributePrefix(int i) {
        if (currentEvent == START_ELEMENT) {
            return getAttribute(i).getPrefix();
        } else {
            throw new IllegalStateException(
                    "attribute prefix accessed in illegal event!");
        }
    }

    String getAttributeLocalName(int i) {
        if (currentEvent == START_ELEMENT) {
            return getAttribute(i).getLocalName();
        } else {
            throw new IllegalStateException(
                    "attribute localName accessed in illegal event!");
        }
    }

    String getAttributeNamespace(int i) {
        if (currentEvent == START_ELEMENT) {
            return getAttribute(i).getNamespaceURI();
        } else {
            throw new IllegalStateException(
                    "attribute nameSpace accessed in illegal event!");
        }
    }

    QName getAttributeName(int i) {
        if (currentEvent == START_ELEMENT) {
            return getAttribute(i).getQName();
        } else {
            throw new IllegalStateException(
                    "attribute count accessed in illegal event!");
        }
    }

    int getAttributeCount() {
        if (currentEvent == START_ELEMENT) {
            loadAttributes();
            return attributeCount;
        } else {
            throw new IllegalStateException(
                    "attribute count accessed in illegal event (" +
                            currentEvent + ")!");
        }
    }

    String getAttributeValue(String s, String s1) {
        if (currentEvent == START_ELEMENT) {
            QName qname = new QName(s, s1);
            OMAttribute attr = ((OMElement)node).getAttribute(qname);
            return attr == null ? null : attr.getAttributeValue();
        } else {
            throw new IllegalStateException(
                    "attribute type accessed in illegal event!");
        }
    }

    Boolean isWhiteSpace() {
        return null;
    }

    String getNamespaceURI(String prefix) {
        if (currentEvent == START_ELEMENT || currentEvent == END_ELEMENT) {

            if (node instanceof OMElement) {
                OMNamespace namespaceURI =
                        ((OMElement) node).findNamespaceURI(prefix);
                return namespaceURI != null ? namespaceURI.getNamespaceURI() : null;
            }
        }
        return null;
    }

    boolean hasNext() throws XMLStreamException {
        // When we reach the end of the document, we switch to EndDocumentState.
        // Therefore we can always return true here.
        return true;
    }

    String getElementText() throws XMLStreamException {
        // Let PullSerializer handle this method
        return null;
    }

    /**
     * Advance to the next node if it is available.
     * <p>
     * The following table describes the possible return values and postconditions:
     * <p>
     * <table border="2" rules="all" cellpadding="4" cellspacing="0">
     * <tr>
     * <th>Outcome</th>
     * <th>Return value</th>
     * <th>Postconditions</th>
     * </tr>
     * <tr>
     * <td>Next node is available</td>
     * <td><code>true</code></td>
     * <td>{@link #node} and {@link #visited} have been updated</td>
     * </tr>
     * <tr>
     * <td>Next node has not been instantiated</td>
     * <td><code>false</code></td>
     * <td>{@link #node} is set to the parent of the next node that would be created</td>
     * </tr>
     * </table>
     *
     * @return <code>true</code> if the next node is available, <code>false</code> if the next node
     *         has not been instantiated yet and the serializer should be switched to pull through
     *         mode
     */
    private boolean nextNode() {
        if (node == null) {
            // We get here if rootNode is an element and the current event is START_DOCUMENT
            assert !visited;
            node = rootNode;
            return true;
        } else if (node instanceof OMContainer && !visited) {
            IContainer current = (IContainer)node;
            OMNode firstChild = cache ? current.getFirstOMChild() : current.getFirstOMChildIfAvailable();
            if (firstChild != null) {
                node = firstChild;
                visited = false;
                return true;
            } else if (node.isComplete()) {
                visited = true;
                return true;
            } else {
                return false;
            }
        } else if (node == rootNode) {
            // We get here if rootNode is an element and the next event is END_DOCUMENT
            node = null;
            visited = true;
            return true;
        } else {
            OMNodeEx current = (OMNodeEx)node;
            OMNode nextSibling = cache ? current.getNextOMSibling() : current.getNextOMSiblingIfAvailable();
            if (nextSibling != null) {
                node = nextSibling;
                visited = false;
                return true;
            } else {
                OMContainer parent = current.getParent();
                node = parent;
                if (parent.isComplete() || parent.getBuilder() == null) { // TODO: review this condition
                    visited = true;
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
   
    void next() throws XMLStreamException {
        if (nextNode()) {
            if (node instanceof OMSourcedElement) {
                OMSourcedElement element = (OMSourcedElement)node;
                if (!element.isExpanded()) {
                    OMDataSource ds = element.getDataSource();
                    if (ds != null) {
                        if (serializer.isDataSourceALeaf()) {
                            this.ds = ds;
                            currentEvent = -1;
                            // Mark the node as visited so that we continue with the next sibling
                            visited = true;
                            return;
                        }
                        if (!(OMDataSourceUtil.isPushDataSource(ds)
                            || (cache && OMDataSourceUtil.isDestructiveRead(ds)))) {
                            XMLStreamReader reader = ds.getReader();
                            while (reader.next() != START_ELEMENT) {
                                // Just loop
                            }
                            serializer.pushState(new IncludeWrapper(serializer, reader));
                            visited = true;
                            return;
                        }
                    }
                }
            }
            if (node == null || node instanceof OMDocument) {
                assert visited;
                serializer.switchState(EndDocumentState.INSTANCE);
                return;
            } else if (node instanceof OMElement) {
                currentEvent = visited ? END_ELEMENT : START_ELEMENT;
            } else {
                currentEvent = ((OMNode)node).getType();
            }
            ds = null;
            attributeCount = -1;
            namespaceCount = -1;
        } else {
            OMContainer container = (OMContainer)node;
            StAXOMBuilder builder = (StAXOMBuilder)container.getBuilder();
            int depth = 1;
            // Find the root node for the builder (i.e. the topmost node having the same
            // builder as the current node)
            while (container != rootNode && container instanceof OMElement) {
                OMContainer parent = ((OMElement)container).getParent();
                if (parent.getBuilder() != builder) {
                    break;
                }
                container = parent;
                depth++;
            }
            XMLStreamReader reader = builder.disableCaching();
            if (log.isDebugEnabled()) {
                log.debug("Switching to pull-through mode; first event is " + XMLEventUtils.getEventTypeString(reader.getEventType()) + "; depth is " + depth);
            }
            PullThroughWrapper wrapper = new PullThroughWrapper(serializer, builder, container, reader, depth);
            serializer.pushState(wrapper);
            node = container;
            visited = true;
        }
    }

    int nextTag() throws XMLStreamException {
        // Let PullSerializer handle this method
        return -1;
    }

    Object getProperty(String s) throws IllegalArgumentException {
        OMContainer container;
        if (node == null) {
            container = rootNode;
        } else if (node instanceof OMContainer) {
            container = (OMContainer)node;
        } else {
            container = ((OMNode)node).getParent();
        }
        OMXMLParserWrapper builder = container.getBuilder();
        // Delegate to the builder's parser.
        if (builder != null && builder instanceof StAXBuilder) {
            StAXBuilder staxBuilder = (StAXBuilder) builder;
            if (!staxBuilder.isClosed()) {
                // If the parser was closed by something other
                // than the builder, an IllegalStateException is
                // thrown.  For now, return null as this is unexpected
                // by the caller.
                try {
                    return ((StAXBuilder) builder).getReaderProperty(s);
                } catch (IllegalStateException ise) {
                    return null;
                }
            }
        }
        return null;
    }

    NamespaceContext getNamespaceContext() {
        return new MapBasedNamespaceContext(getAllNamespaces(node));
    }

    String getEncoding() {
        if (currentEvent == START_DOCUMENT) {
            if (node instanceof OMDocument) {
                return ((OMDocument)node).getCharsetEncoding();
            } else {
                return null;
            }
        } else {
            throw new IllegalStateException();
        }
    }

    String getVersion() {
        return "1.0"; // todo put the constant
    }

    boolean isStandalone() {
        return true;
    }

    boolean standaloneSet() {
        return false;
    }

    String getCharacterEncodingScheme() {
        if (currentEvent == START_DOCUMENT) {
            if (node instanceof OMDocument) {
                return ((OMDocument)node).getXMLEncoding();
            } else {
                return null;
            }
        } else {
            throw new IllegalStateException();
        }
    }

    String getPITarget() {
        if (currentEvent == PROCESSING_INSTRUCTION) {
            return ((OMProcessingInstruction)node).getTarget();
        } else {
            throw new IllegalStateException();
        }
    }

    String getPIData() {
        if (currentEvent == PROCESSING_INSTRUCTION) {
            return ((OMProcessingInstruction)node).getValue();
        } else {
            throw new IllegalStateException();
        }
    }

    /*
     *
     * ################################################################
     * DataHandlerReader extension methods
     * ################################################################
     *
     */

    public boolean isBinary() {
        if (node instanceof OMText) {
            return ((OMText)node).isBinary();
        } else {
            return false;
        }
    }

    public boolean isOptimized() {
        if (node instanceof OMText) {
            return ((OMText)node).isOptimized();
        } else {
            throw new IllegalStateException();
        }
    }

    public boolean isDeferred() {
        if (node instanceof OMText) {
            // TODO: we should support deferred building of the DataHandler
            return false;
        } else {
            throw new IllegalStateException();
        }
    }

    public String getContentID() {
        if (node instanceof OMText) {
            return ((OMText)node).getContentID();
        } else {
            throw new IllegalStateException();
        }
    }

    public DataHandler getDataHandler() throws XMLStreamException {
        if (node instanceof OMText) {
            return (DataHandler)((OMText)node).getDataHandler();
        } else {
            throw new IllegalStateException();
        }
    }

    public DataHandlerProvider getDataHandlerProvider() {
        throw new IllegalStateException();
    }

    /*
     *
     * ################################################################
     * DTDReader extension methods
     * ################################################################
     *
     */

    public String getRootName() {
        if (currentEvent == DTD) {
            return ((OMDocType)node).getRootName();
        } else {
            throw new IllegalStateException();
        }
    }

    public String getPublicId() {
        if (currentEvent == DTD) {
            return ((OMDocType)node).getPublicId();
        } else {
            throw new IllegalStateException();
        }
    }

    public String getSystemId() {
        if (currentEvent == DTD) {
            return ((OMDocType)node).getSystemId();
        } else {
            throw new IllegalStateException();
        }
    }

    /*
     * ####################################################################
     * Other helper methods
     * ####################################################################
     */

    private Map getAllNamespaces(OMSerializable contextNode) {
        if (contextNode == null) {
            return Collections.EMPTY_MAP;
        }
        OMContainer context;
        if (contextNode instanceof OMContainer) {
            context = (OMContainer)contextNode;
        } else {
            context = ((OMNode)contextNode).getParent();
        }
        Map nsMap = new LinkedHashMap();
        while (context != null && !(context instanceof OMDocument)) {
            OMElement element = (OMElement) context;
            for (Iterator it = element.getAllDeclaredNamespaces(); it.hasNext(); ) {
                addNamespaceToMap((OMNamespace) it.next(), nsMap);
            }
            if (element.getNamespace() != null) {
                addNamespaceToMap(element.getNamespace(), nsMap);
            }
            for (Iterator it = element.getAllAttributes(); it.hasNext(); ) {
                OMAttribute attr = (OMAttribute) it.next();
                if (attr.getNamespace() != null) {
                    addNamespaceToMap(attr.getNamespace(), nsMap);
                }
            }
            context = element.getParent();
        }
        return nsMap;
    }

    private void addNamespaceToMap(OMNamespace ns, Map map) {
        if (map.get(ns.getPrefix()) == null) {
            map.put(ns.getPrefix(), ns.getNamespaceURI());
        }
    }

    /**
     * @return OMDataSource associated with the current node or Null
     */
    OMDataSource getDataSource() {
        if (log.isDebugEnabled() && ds != null) {
            log.debug("Exposed OMDataSource: " + ds);
        }
        return ds;
    }

    void released() throws XMLStreamException {
    }

    void restored() throws XMLStreamException {
        next();
    }
   
    public String toString() {
        return super.toString() + "[cache=" + cache + ",document=" + (rootNode instanceof OMDocument) + "]";
    }
}
TOP

Related Classes of org.apache.axiom.om.impl.common.serializer.pull.Navigator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.