001/* 002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 003 * 004 * This software is open source. 005 * See the bottom of this file for the licence. 006 * 007 * $Id: QNameCache.java,v 1.6 2001/08/28 06:43:18 jstrachan Exp $ 008 */ 009 010package org.dom4j.tree; 011 012import java.util.ArrayList; 013import java.util.HashMap; 014import java.util.Iterator; 015import java.util.List; 016import java.util.Map; 017 018import org.dom4j.DocumentFactory; 019import org.dom4j.QName; 020import org.dom4j.Namespace; 021 022/** <p><code>QNameCache</code> caches instances of <code>QName</code> 023 * for reuse both across documents and within documents.</p> 024 * 025 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a> 026 * @version $Revision: 1.6 $ 027 */ 028public class QNameCache { 029 030 /** Cache of {@link QName} instances with no namespace */ 031 protected Map noNamespaceCache = new HashMap(); 032 033 /** Cache of {@link Map} instances indexed by namespace which contain 034 * caches of {@link QName} for each name 035 */ 036 protected Map namespaceCache = new HashMap(); 037 038 /** The document factory associated with new QNames instances in this cache 039 * or null if no instances should be associated by default 040 */ 041 private DocumentFactory documentFactory; 042 043 044 public QNameCache() { 045 } 046 047 public QNameCache(DocumentFactory documentFactory) { 048 this.documentFactory = documentFactory; 049 } 050 051 /** Returns a list of all the QName instances currently used 052 */ 053 public List getQNames() { 054 List answer = new ArrayList(); 055 answer.addAll( noNamespaceCache.values() ); 056 for ( Iterator iter = namespaceCache.values().iterator(); iter.hasNext(); ) { 057 Map map = (Map) iter.next(); 058 answer.addAll( map.values() ); 059 } 060 return answer; 061 } 062 063 /** @return the QName for the given name and no namepsace 064 */ 065 public QName get(String name) { 066 QName answer = (QName) noNamespaceCache.get(name); 067 if (answer == null) { 068 answer = createQName(name); 069 answer.setDocumentFactory( documentFactory ); 070 noNamespaceCache.put(name, answer); 071 } 072 return answer; 073 } 074 075 /** @return the QName for the given local name and namepsace 076 */ 077 public QName get(String name, Namespace namespace) { 078 Map cache = getNamespaceCache(namespace); 079 QName answer = (QName) cache.get(name); 080 if (answer == null) { 081 answer = createQName(name, namespace); 082 answer.setDocumentFactory( documentFactory ); 083 cache.put(name, answer); 084 } 085 return answer; 086 } 087 088 089 /** @return the QName for the given local name, qualified name and namepsace 090 */ 091 public QName get(String localName, Namespace namespace, String qualifiedName) { 092 Map cache = getNamespaceCache(namespace); 093 QName answer = (QName) cache.get(localName); 094 if (answer == null) { 095 answer = createQName(localName, namespace, qualifiedName); 096 answer.setDocumentFactory( documentFactory ); 097 cache.put(localName, answer); 098 } 099 return answer; 100 } 101 102 103 public QName get(String qualifiedName, String uri) { 104 int index = qualifiedName.indexOf( ':' ); 105 if ( index < 0 ) { 106 return get( qualifiedName, Namespace.get( uri ) ); 107 } 108 else { 109 String name = qualifiedName.substring( index + 1 ); 110 String prefix = qualifiedName.substring( 0, index ); 111 return get(name, Namespace.get( prefix, uri )); 112 } 113 } 114 115 116 /** @return the cached QName instance if there is one or adds the given 117 * qname to the cache if not 118 */ 119 public QName intern(QName qname) { 120 return get(qname.getName(), qname.getNamespace(), qname.getQualifiedName()); 121 } 122 123 /** @return the cache for the given namespace. If one does not 124 * currently exist it is created. 125 */ 126 protected Map getNamespaceCache(Namespace namespace) { 127 if (namespace == Namespace.NO_NAMESPACE) { 128 return noNamespaceCache; 129 } 130 Map answer = (Map) namespaceCache.get(namespace); 131 if (answer == null) { 132 answer = createMap(); 133 namespaceCache.put(namespace, answer); 134 } 135 return answer; 136 } 137 138 /** A factory method 139 * @return a newly created {@link Map} instance. 140 */ 141 protected Map createMap() { 142 return new HashMap(); 143 } 144 145 /** Factory method to create a new QName object 146 * which can be overloaded to create derived QName instances 147 */ 148 protected QName createQName(String name) { 149 return new QName(name); 150 } 151 152 /** Factory method to create a new QName object 153 * which can be overloaded to create derived QName instances 154 */ 155 protected QName createQName(String name, Namespace namespace) { 156 return new QName(name, namespace); 157 } 158 159 /** Factory method to create a new QName object 160 * which can be overloaded to create derived QName instances 161 */ 162 protected QName createQName(String name, Namespace namespace, String qualifiedName) { 163 return new QName(name, namespace, qualifiedName); 164 } 165} 166 167 168 169 170/* 171 * Redistribution and use of this software and associated documentation 172 * ("Software"), with or without modification, are permitted provided 173 * that the following conditions are met: 174 * 175 * 1. Redistributions of source code must retain copyright 176 * statements and notices. Redistributions must also contain a 177 * copy of this document. 178 * 179 * 2. Redistributions in binary form must reproduce the 180 * above copyright notice, this list of conditions and the 181 * following disclaimer in the documentation and/or other 182 * materials provided with the distribution. 183 * 184 * 3. The name "DOM4J" must not be used to endorse or promote 185 * products derived from this Software without prior written 186 * permission of MetaStuff, Ltd. For written permission, 187 * please contact dom4j-info@metastuff.com. 188 * 189 * 4. Products derived from this Software may not be called "DOM4J" 190 * nor may "DOM4J" appear in their names without prior written 191 * permission of MetaStuff, Ltd. DOM4J is a registered 192 * trademark of MetaStuff, Ltd. 193 * 194 * 5. Due credit should be given to the DOM4J Project 195 * (http://dom4j.org/). 196 * 197 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS 198 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 199 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 200 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 201 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 202 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 203 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 204 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 205 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 206 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 207 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 208 * OF THE POSSIBILITY OF SUCH DAMAGE. 209 * 210 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved. 211 * 212 * $Id: QNameCache.java,v 1.6 2001/08/28 06:43:18 jstrachan Exp $ 213 */