View Javadoc

    1   /*
    2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
    3    *
    4    * This software is open source.
    5    * See the bottom of this file for the licence.
    6    */
    7
    8   package org.dom4j.tree;
    9
    10  import java.util.ArrayList;
    11  import java.util.Collections;
    12  import java.util.HashMap;
    13  import java.util.Iterator;
    14  import java.util.List;
    15  import java.util.Map;
    16  import java.util.WeakHashMap;
    17
    18  import org.dom4j.DocumentFactory;
    19  import org.dom4j.Namespace;
    20  import org.dom4j.QName;
    21
    22  /***
    23   * <p>
    24   * <code>QNameCache</code> caches instances of <code>QName</code> for reuse
    25   * both across documents and within documents.
    26   * </p>< < < < < < < QNameCache.java
    27   *
    28   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
    29   * @version $Revision: 1.16 $ =======
    30   *
    31   * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
    32   * @version $Revision: 1.16 $ >>>>>>> 1.15
    33   */
    34  public class QNameCache {
    35      /*** Cache of {@link QName}instances with no namespace */
    36      protected Map noNamespaceCache = Collections
    37              .synchronizedMap(new WeakHashMap());
    38
    39      /***
    40       * Cache of {@link Map}instances indexed by namespace which contain caches
    41       * of {@link QName}for each name
    42       */
    43      protected Map namespaceCache = Collections
    44              .synchronizedMap(new WeakHashMap());
    45
    46      /***
    47       * The document factory associated with new QNames instances in this cache
    48       * or null if no instances should be associated by default
    49       */
    50      private DocumentFactory documentFactory;
    51
    52      public QNameCache() {
    53      }
    54
    55      public QNameCache(DocumentFactory documentFactory) {
    56          this.documentFactory = documentFactory;
    57      }
    58
    59      /***
    60       * Returns a list of all the QName instances currently used
    61       *
    62       * @return DOCUMENT ME!
    63       */
    64      public List getQNames() {
    65          List answer = new ArrayList();
    66          answer.addAll(noNamespaceCache.values());
    67
    68          for (Iterator it = namespaceCache.values().iterator(); it.hasNext();) {
    69              Map map = (Map) it.next();
    70              answer.addAll(map.values());
    71          }
    72
    73          return answer;
    74      }
    75
    76      /***
    77       * DOCUMENT ME!
    78       *
    79       * @param name
    80       *            DOCUMENT ME!
    81       *
    82       * @return the QName for the given name and no namepsace
    83       */
    84      public QName get(String name) {
    85          QName answer = null;
    86
    87          if (name != null) {
    88              answer = (QName) noNamespaceCache.get(name);
    89          } else {
    90              name = "";
    91          }
    92
    93          if (answer == null) {
    94              answer = createQName(name);
    95              answer.setDocumentFactory(documentFactory);
    96              noNamespaceCache.put(name, answer);
    97          }
    98
    99          return answer;
    100     }
    101
    102     /***
    103      * DOCUMENT ME!
    104      *
    105      * @param name
    106      *            DOCUMENT ME!
    107      * @param namespace
    108      *            DOCUMENT ME!
    109      *
    110      * @return the QName for the given local name and namepsace
    111      */
    112     public QName get(String name, Namespace namespace) {
    113         Map cache = getNamespaceCache(namespace);
    114         QName answer = null;
    115
    116         if (name != null) {
    117             answer = (QName) cache.get(name);
    118         } else {
    119             name = "";
    120         }
    121
    122         if (answer == null) {
    123             answer = createQName(name, namespace);
    124             answer.setDocumentFactory(documentFactory);
    125             cache.put(name, answer);
    126         }
    127
    128         return answer;
    129     }
    130
    131     /***
    132      * DOCUMENT ME!
    133      *
    134      * @param localName
    135      *            DOCUMENT ME!
    136      * @param namespace
    137      *            DOCUMENT ME!
    138      * @param qName
    139      *            DOCUMENT ME!
    140      *
    141      * @return the QName for the given local name, qualified name and namepsace
    142      */
    143     public QName get(String localName, Namespace namespace, String qName) {
    144         Map cache = getNamespaceCache(namespace);
    145         QName answer = null;
    146
    147         if (localName != null) {
    148             answer = (QName) cache.get(localName);
    149         } else {
    150             localName = "";
    151         }
    152
    153         if (answer == null) {
    154             answer = createQName(localName, namespace, qName);
    155             answer.setDocumentFactory(documentFactory);
    156             cache.put(localName, answer);
    157         }
    158
    159         return answer;
    160     }
    161
    162     public QName get(String qualifiedName, String uri) {
    163         int index = qualifiedName.indexOf(':');
    164
    165         if (index < 0) {
    166             return get(qualifiedName, Namespace.get(uri));
    167         } else {
    168             String name = qualifiedName.substring(index + 1);
    169             String prefix = qualifiedName.substring(0, index);
    170
    171             return get(name, Namespace.get(prefix, uri));
    172         }
    173     }
    174
    175     /***
    176      * DOCUMENT ME!
    177      *
    178      * @param qname
    179      *            DOCUMENT ME!
    180      *
    181      * @return the cached QName instance if there is one or adds the given qname
    182      *         to the cache if not
    183      */
    184     public QName intern(QName qname) {
    185         return get(qname.getName(), qname.getNamespace(), qname
    186                 .getQualifiedName());
    187     }
    188
    189     /***
    190      * DOCUMENT ME!
    191      *
    192      * @param namespace
    193      *            DOCUMENT ME!
    194      *
    195      * @return the cache for the given namespace. If one does not currently
    196      *         exist it is created.
    197      */
    198     protected Map getNamespaceCache(Namespace namespace) {
    199         if (namespace == Namespace.NO_NAMESPACE) {
    200             return noNamespaceCache;
    201         }
    202
    203         Map answer = null;
    204
    205         if (namespace != null) {
    206             answer = (Map) namespaceCache.get(namespace);
    207         }
    208
    209         if (answer == null) {
    210             answer = createMap();
    211             namespaceCache.put(namespace, answer);
    212         }
    213
    214         return answer;
    215     }
    216
    217     /***
    218      * A factory method
    219      *
    220      * @return a newly created {@link Map}instance.
    221      */
    222     protected Map createMap() {
    223         return Collections.synchronizedMap(new HashMap());
    224     }
    225
    226     /***
    227      * Factory method to create a new QName object which can be overloaded to
    228      * create derived QName instances
    229      *
    230      * @param name
    231      *            DOCUMENT ME!
    232      *
    233      * @return DOCUMENT ME!
    234      */
    235     protected QName createQName(String name) {
    236         return new QName(name);
    237     }
    238
    239     /***
    240      * Factory method to create a new QName object which can be overloaded to
    241      * create derived QName instances
    242      *
    243      * @param name
    244      *            DOCUMENT ME!
    245      * @param namespace
    246      *            DOCUMENT ME!
    247      *
    248      * @return DOCUMENT ME!
    249      */
    250     protected QName createQName(String name, Namespace namespace) {
    251         return new QName(name, namespace);
    252     }
    253
    254     /***
    255      * Factory method to create a new QName object which can be overloaded to
    256      * create derived QName instances
    257      *
    258      * @param name
    259      *            DOCUMENT ME!
    260      * @param namespace
    261      *            DOCUMENT ME!
    262      * @param qualifiedName
    263      *            DOCUMENT ME!
    264      *
    265      * @return DOCUMENT ME!
    266      */
    267     protected QName createQName(String name, Namespace namespace,
    268             String qualifiedName) {
    269         return new QName(name, namespace, qualifiedName);
    270     }
    271 }
    272
    273
    274
    275 /*
    276  * Redistribution and use of this software and associated documentation
    277  * ("Software"), with or without modification, are permitted provided that the
    278  * following conditions are met:
    279  *
    280  * 1. Redistributions of source code must retain copyright statements and
    281  * notices. Redistributions must also contain a copy of this document.
    282  *
    283  * 2. Redistributions in binary form must reproduce the above copyright notice,
    284  * this list of conditions and the following disclaimer in the documentation
    285  * and/or other materials provided with the distribution.
    286  *
    287  * 3. The name "DOM4J" must not be used to endorse or promote products derived
    288  * from this Software without prior written permission of MetaStuff, Ltd. For
    289  * written permission, please contact dom4j-info@metastuff.com.
    290  *
    291  * 4. Products derived from this Software may not be called "DOM4J" nor may
    292  * "DOM4J" appear in their names without prior written permission of MetaStuff,
    293  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
    294  *
    295  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
    296  *
    297  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
    298  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    299  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    300  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
    301  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    302  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    303  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    304  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    305  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    306  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    307  * POSSIBILITY OF SUCH DAMAGE.
    308  *
    309  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
    310  */