📄 namespacestack.java
字号:
/* * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. * * This software is open source. * See the bottom of this file for the licence. * * $Id: NamespaceStack.java,v 1.5 2003/11/02 18:04:59 per_nyfelt Exp $ */package org.dom4j.tree;import org.dom4j.*;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;/** NamespaceStack implements a stack of namespaces and optionally * maintains a cache of all the fully qualified names (<code>QName</code>) * which are in scope. This is useful when building or navigating a <i>dom4j</i> * document. * * @author <a href="mailto:jstrachan@apache.org">James Strachan</a> * @version $Revision: 1.5 $ */public class NamespaceStack { /** The factory used to create new <code>AbstractNamespace</code> instances */ private NodeFactory nodeFactory; /** The Stack of namespaces */ private ArrayList namespaceStack = new ArrayList(); /** The cache of qualifiedNames to QNames per namespace context */ private ArrayList namespaceCacheList = new ArrayList(); /** A cache of current namespace context cache of mapping from qualifiedName to QName */ private Map currentNamespaceCache; /** A cache of mapping from qualifiedName to QName before any namespaces are declared */ private Map rootNamespaceCache = new HashMap(); /** Caches the default namespace defined via xmlns="" */ private Namespace defaultNamespace; public NamespaceStack() { this.nodeFactory = DocumentFactory.getInstance(); } /** * @deprecated Use NamespaceStack(NodeFactory) instead. */ public NamespaceStack(DocumentFactory documentFactory) { this.nodeFactory = documentFactory; } public NamespaceStack(NodeFactory nodeFactory) { this.nodeFactory = nodeFactory; } /** Pushes the given namespace onto the stack so that its prefix * becomes available. * * @param namespace is the <code>AbstractNamespace</code> to add to the stack. */ public void push(Namespace namespace) { namespaceStack.add( namespace ); namespaceCacheList.add( null ); currentNamespaceCache = null; String prefix = namespace.getPrefix(); if ( prefix == null || prefix.length() == 0 ) { defaultNamespace = namespace; } } /** Pops the most recently used <code>AbstractNamespace</code> from * the stack * * @return AbstractNamespace popped from the stack */ public Namespace pop() { return remove( namespaceStack.size() - 1 ); } /** @return the number of namespaces on the stackce stack. */ public int size() { return namespaceStack.size(); } /** Clears the stack */ public void clear() { namespaceStack.clear(); namespaceCacheList.clear(); rootNamespaceCache.clear(); currentNamespaceCache = null; } /** @return the namespace at the specified index on the stack */ public AbstractNamespace getNamespace( int index ) { return (AbstractNamespace) namespaceStack.get( index ); } /** @return the namespace for the given prefix or null * if it could not be found. */ public Namespace getNamespaceForPrefix( String prefix ) { if ( prefix == null ) { prefix = ""; } for ( int i = namespaceStack.size() - 1; i >= 0; i-- ) { Namespace namespace = (Namespace) namespaceStack.get(i); if ( prefix.equals( namespace.getPrefix() ) ) { return namespace; } } return null; } /** @return the URI for the given prefix or null if it * could not be found. */ public String getURI( String prefix ) { Namespace namespace = getNamespaceForPrefix( prefix ); return ( namespace != null ) ? namespace.getURI() : null; } /** @return true if the given prefix is in the stack. */ public boolean contains( Namespace namespace ) { String prefix = namespace.getPrefix(); Namespace current = null; if ( prefix == null || prefix.length() == 0 ) { current = getDefaultNamespace(); } else { current = getNamespaceForPrefix( prefix ); } if ( current == null ) { return false; } if ( current == namespace ) { return true; } return namespace.getURI().equals( current.getURI() ); } public QName getQName( String namespaceURI, String localName, String qualifiedName ) { if ( localName == null ) { localName = qualifiedName; } else if ( qualifiedName == null ) { qualifiedName = localName; } if ( namespaceURI == null ) { namespaceURI = ""; } String prefix = ""; int index = qualifiedName.indexOf(":"); if (index > 0) { prefix = qualifiedName.substring(0, index); if (localName.trim().length() == 0) { localName = qualifiedName.substring(index+1); } } else if (localName.trim().length() == 0) { localName = qualifiedName; } Namespace namespace = createNamespace( prefix, namespaceURI ); return pushQName( localName, qualifiedName, namespace, prefix ); } public QName getAttributeQName( String namespaceURI, String localName, String qualifiedName ) { if ( qualifiedName == null ) { qualifiedName = localName; } Map map = getNamespaceCache(); QName answer = (QName) map.get( qualifiedName ); if ( answer != null ) { return answer; } if ( localName == null ) { localName = qualifiedName; } if ( namespaceURI == null ) { namespaceURI = ""; } Namespace namespace = null; String prefix = ""; int index = qualifiedName.indexOf(":"); if (index > 0) { prefix = qualifiedName.substring(0, index); namespace = createNamespace( prefix, namespaceURI ); if ( localName.trim().length() == 0) { localName = qualifiedName.substring(index+1); } } else { // attributes with no prefix have no namespace namespace = AbstractNamespace.NO_NAMESPACE; if ( localName.trim().length() == 0) { localName = qualifiedName; } } answer = pushQName( localName, qualifiedName, namespace, prefix ); map.put( qualifiedName, answer ); return answer; } /** Adds a namepace to the stack with the given prefix and URI */ public void push( String prefix, String uri ) { if ( uri == null ) { uri = ""; } Namespace namespace = createNamespace( prefix, uri ); push( namespace ); } /** Adds a new namespace to the stack */ public Namespace addNamespace( String prefix, String uri ) { Namespace namespace = createNamespace( prefix, uri ); push( namespace ); return namespace; } /** Pops a namepace from the stack with the given prefix and URI */ public Namespace pop( String prefix ) { if ( prefix == null ) { prefix = ""; } Namespace namespace = null; for (int i = namespaceStack.size() - 1; i >= 0; i-- ) { Namespace ns = (Namespace) namespaceStack.get(i); if ( prefix.equals( ns.getPrefix() ) ) { remove(i); namespace = ns; break; } } if ( namespace == null ) { System.out.println( "Warning: missing namespace prefix ignored: " + prefix ); } return namespace; } public String toString() { return super.toString() + " Stack: " + namespaceStack.toString(); } /** * @deprecated Use getNodeFactory() instead */ public DocumentFactory getDocumentFactory() { if (getNodeFactory() instanceof XPathFactory) { return new DelegateDocumentFactory(getNodeFactory(), (XPathFactory) getNodeFactory()); } else { return new DelegateDocumentFactory(getNodeFactory(), DocumentFactory.getInstance()); } } /** * @deprecated Use setNodeFactory(NodeFactory) instead */ public void setDocumentFactory(DocumentFactory documentFactory) { this.nodeFactory = documentFactory; } public NodeFactory getNodeFactory() { return nodeFactory; } public void setNodeFactory(NodeFactory nodeFactory) { this.nodeFactory = nodeFactory; } public Namespace getDefaultNamespace() { if ( defaultNamespace == null ) { defaultNamespace = findDefaultNamespace(); } return defaultNamespace; } // Implementation methods //------------------------------------------------------------------------- /** Adds the QName to the stack of available QNames */ protected QName pushQName( String localName, String qualifiedName, Namespace namespace, String prefix ) { if ( prefix == null || prefix.length() == 0 ) { this.defaultNamespace = null; } return createQName( localName, qualifiedName, namespace ); } /** Factory method to creeate new QName instances. By default this method * interns the QName */ protected QName createQName( String localName, String qualifiedName, Namespace namespace ) { return getNodeFactory().createQName( localName, namespace ); } /** Factory method to creeate new AbstractNamespace instances. By default this method * interns the AbstractNamespace */ protected Namespace createNamespace( String prefix, String namespaceURI ) { return getNodeFactory().createNamespace( prefix, namespaceURI ); } /** Attempts to find the current default namespace on the stack right now or returns null if one * could not be found */ protected Namespace findDefaultNamespace() { for ( int i = namespaceStack.size() - 1; i >= 0; i-- ) { Namespace namespace = (Namespace) namespaceStack.get(i); if ( namespace != null ) { String prefix = namespace.getPrefix(); if ( prefix == null || namespace.getPrefix().length() == 0 ) { return namespace; } } } return null; } /** Removes the namespace at the given index of the stack */ protected Namespace remove(int index) { Namespace namespace = (Namespace) namespaceStack.remove(index); namespaceCacheList.remove(index); defaultNamespace = null; currentNamespaceCache = null; return namespace; } protected Map getNamespaceCache() { if ( currentNamespaceCache == null ) { int index = namespaceStack.size() - 1; if ( index < 0 ) { currentNamespaceCache = rootNamespaceCache; } else { currentNamespaceCache = (Map) namespaceCacheList.get(index); if ( currentNamespaceCache == null ) { currentNamespaceCache = new HashMap(); namespaceCacheList.set(index, currentNamespaceCache); } } } return currentNamespaceCache; }}/* * Redistribution and use of this software and associated documentation * ("Software"), with or without modification, are permitted provided * that the following conditions are met: * * 1. Redistributions of source code must retain copyright * statements and notices. Redistributions must also contain a * copy of this document. * * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. The name "DOM4J" must not be used to endorse or promote * products derived from this Software without prior written * permission of MetaStuff, Ltd. For written permission, * please contact dom4j-info@metastuff.com. * * 4. Products derived from this Software may not be called "DOM4J" * nor may "DOM4J" appear in their names without prior written * permission of MetaStuff, Ltd. DOM4J is a registered * trademark of MetaStuff, Ltd. * * 5. Due credit should be given to the DOM4J Project * (http://dom4j.org/). * * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. * * $Id: NamespaceStack.java,v 1.5 2003/11/02 18:04:59 per_nyfelt Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -