View Javadoc

1   /*
2    * Copyright [2006] [University Corporation for Advanced Internet Development, Inc.]
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.xml.util;
18  
19  import java.util.Collections;
20  import java.util.Map;
21  import java.util.Set;
22  
23  import net.jcip.annotations.NotThreadSafe;
24  
25  import org.opensaml.xml.XMLObject;
26  
27  /**
28   * Class which provides storage for the ID-to-XMLObject index mapping on an owning {@link org.opensaml.xml.XMLObject}.
29   */
30  @NotThreadSafe
31  public class IDIndex {
32      
33      /** The XMLObject which owns this ID index. */
34      private XMLObject owner;
35      
36      /** Mapping of ID attributes to XMLObjects in the subtree rooted at this object's owner.
37       * This allows constant-time dereferencing of ID-typed attributes within the subtree.  */
38      private Map<String, XMLObject> idMappings;
39  
40      /**
41       * Constructor.
42       *
43       * @param newOwner the XMLObject which owns this ID-to-XMLObject index
44       * 
45       * @throws NullPointerException thrown if the given XMLObject is null
46       */
47      public IDIndex(XMLObject newOwner) throws NullPointerException {
48          if (newOwner == null) {
49              throw new NullPointerException("Attribute owner XMLObject may not be null");
50          }
51          
52          owner = newOwner;
53          idMappings = new LazyMap<String, XMLObject>();
54      }
55      
56  
57      /**
58       * Register an ID-to-XMLObject mapping for one of this object's owner's children.
59       * 
60       * @param id the XMLObject child's ID attribute value
61       * @param referent the XMLObject child
62       */
63      public void registerIDMapping(String id, XMLObject referent) {
64          if (id == null) {
65              return;
66          }
67          
68          idMappings.put(id, referent);
69          if (owner.hasParent()) {
70              owner.getParent().getIDIndex().registerIDMapping(id, referent);
71          }
72      }
73      
74      /**
75       * Register multiple ID-to-XMLObject mappings for this object's owner's children.
76       * 
77       * @param idIndex the ID-to-XMLObject mapping to register
78       */
79      public void registerIDMappings(IDIndex idIndex) {
80          if (idIndex == null || idIndex.isEmpty()) {
81              return;
82          }
83          
84          idMappings.putAll(idIndex.getIDMappings());
85          if (owner.hasParent()) {
86              owner.getParent().getIDIndex().registerIDMappings(idIndex);
87          }
88      }
89      
90      /**
91       * Deregister an ID-to-XMLObject mapping for one of this object's owner's children.
92       * 
93       * @param id the ID attribute value of the XMLObject child to deregister
94       */  
95      public void deregisterIDMapping(String id) {
96          if (id == null) {
97              return;
98          }
99          
100         idMappings.remove(id);
101         if (owner.hasParent()) {
102             owner.getParent().getIDIndex().deregisterIDMapping(id);
103         }
104     }
105     
106     /**
107      * Deregister multiple ID-to-XMLObject mappings for this object's owner's children.
108      * 
109      * @param idIndex the ID-to-XMLObject mappings to deregister
110      */
111     public void deregisterIDMappings(IDIndex idIndex) {
112         if (idIndex == null || idIndex.isEmpty()) {
113             return;
114         }
115         
116         for (String id : idIndex.getIDs()) {
117             idMappings.remove(id);
118         }
119         if (owner.hasParent()) {
120             owner.getParent().getIDIndex().deregisterIDMappings(idIndex);
121         }
122     }
123  
124     /**
125      * Lookup and return the XMLObject identified by the specified ID attribute.
126      * 
127      * @param id the ID attribute value to lookup
128      * @return the XMLObject identified by the ID attribute value
129      */
130     public XMLObject lookup(String id) {
131         return idMappings.get(id);
132     }
133     
134     /**
135      * Return whether the index is currently empty.
136      * 
137      * @return true if the index is currently empty
138      */
139     public boolean isEmpty() {
140         return idMappings.isEmpty();
141     }
142     
143     /**
144      * Get the set of ID strings which are the index keys.
145      * 
146      * @return the set of ID strings which are keys to the index
147      */
148     public Set<String> getIDs() {
149         return Collections.unmodifiableSet(idMappings.keySet());
150     }
151     
152     /**
153      * Get the ID-to-XMLObject mappings for this object's object's owner's children.
154      * 
155      * @return the ID-to-XMLObject mapping
156      */
157     protected Map<String, XMLObject> getIDMappings() {
158         return Collections.unmodifiableMap(idMappings);
159     }
160     
161 }