View Javadoc

1   /*
2    * Copyright 2008 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.io.Serializable;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import net.jcip.annotations.NotThreadSafe;
27  
28  /**
29   * A map that is lazy initialized. This map takes very little memory when storing zero or one item.
30   * 
31   * @param <KeyType> the type of the map keys
32   * @param <ValueType> the type of the map values
33   */
34  @NotThreadSafe
35  public class LazyMap<KeyType, ValueType> implements Map<KeyType, ValueType>, Serializable {
36  
37      /** Serial version UID. */
38      private static final long serialVersionUID = 121425595164176639L;
39  
40      /** The delegate map. */
41      private Map<KeyType, ValueType> delegate = Collections.emptyMap();
42  
43      /** {@inheritDoc} */
44      public void clear() {
45          delegate = Collections.emptyMap();
46      }
47  
48      /** {@inheritDoc} */
49      public boolean containsKey(Object key) {
50          return delegate.containsKey(key);
51      }
52  
53      /** {@inheritDoc} */
54      public boolean containsValue(Object value) {
55          return delegate.containsValue(value);
56      }
57  
58      /** {@inheritDoc} */
59      public Set<Entry<KeyType, ValueType>> entrySet() {
60          return delegate.entrySet();
61      }
62  
63      /** {@inheritDoc} */
64      public ValueType get(Object key) {
65          return delegate.get(key);
66      }
67  
68      /** {@inheritDoc} */
69      public boolean isEmpty() {
70          return delegate.isEmpty();
71      }
72  
73      /** {@inheritDoc} */
74      public Set<KeyType> keySet() {
75          return delegate.keySet();
76      }
77  
78      /** {@inheritDoc} */
79      public ValueType put(KeyType key, ValueType value) {
80          if (delegate.isEmpty()) {
81              delegate = Collections.singletonMap(key, value);
82              return null;
83          } else {
84              delegate = buildMap();
85              return delegate.put(key, value);
86          }
87      }
88  
89      /** {@inheritDoc} */
90      public void putAll(Map<? extends KeyType, ? extends ValueType> t) {
91          delegate = buildMap();
92          delegate.putAll(t);
93      }
94  
95      /** {@inheritDoc} */
96      public ValueType remove(Object key) {
97          delegate = buildMap();
98          return delegate.remove(key);
99      }
100 
101     /** {@inheritDoc} */
102     public int size() {
103         return delegate.size();
104     }
105 
106     /** {@inheritDoc} */
107     public Collection<ValueType> values() {
108         return delegate.values();
109     }
110 
111     /**
112      * Builds an appropriate delegate map.
113      * 
114      * @return the delegate map
115      */
116     protected Map<KeyType, ValueType> buildMap() {
117         if (delegate instanceof HashMap) {
118             return delegate;
119         }
120 
121         return new HashMap<KeyType, ValueType>(delegate);
122     }
123 
124     /** {@inheritDoc} */
125     public String toString() {
126         return delegate.toString();
127     }
128 
129     /** {@inheritDoc} */
130     public int hashCode() {
131         return delegate.hashCode();
132     }
133 
134     /** {@inheritDoc} */
135     public boolean equals(Object obj) {
136         if (this == obj) {
137             return true;
138         }
139 
140         if (obj == null || this.getClass() != obj.getClass()) {
141             return false;
142         }
143 
144         return delegate.equals(((LazyMap<?, ?>) obj).delegate);
145     }
146 }