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          delegate = buildMap();
61          return delegate.entrySet();
62      }
63  
64      /** {@inheritDoc} */
65      public ValueType get(Object key) {
66          return delegate.get(key);
67      }
68  
69      /** {@inheritDoc} */
70      public boolean isEmpty() {
71          return delegate.isEmpty();
72      }
73  
74      /** {@inheritDoc} */
75      public Set<KeyType> keySet() {
76          delegate = buildMap();
77          return delegate.keySet();
78      }
79  
80      /** {@inheritDoc} */
81      public ValueType put(KeyType key, ValueType value) {
82          if (delegate.isEmpty()) {
83              delegate = Collections.singletonMap(key, value);
84              return null;
85          } else {
86              delegate = buildMap();
87              return delegate.put(key, value);
88          }
89      }
90  
91      /** {@inheritDoc} */
92      public void putAll(Map<? extends KeyType, ? extends ValueType> t) {
93          delegate = buildMap();
94          delegate.putAll(t);
95      }
96  
97      /** {@inheritDoc} */
98      public ValueType remove(Object key) {
99          delegate = buildMap();
100         return delegate.remove(key);
101     }
102 
103     /** {@inheritDoc} */
104     public int size() {
105         return delegate.size();
106     }
107 
108     /** {@inheritDoc} */
109     public Collection<ValueType> values() {
110         delegate = buildMap();
111         return delegate.values();
112     }
113 
114     /**
115      * Builds an appropriate delegate map.
116      * 
117      * @return the delegate map
118      */
119     protected Map<KeyType, ValueType> buildMap() {
120         if (delegate instanceof HashMap) {
121             return delegate;
122         }
123 
124         return new HashMap<KeyType, ValueType>(delegate);
125     }
126 
127     /** {@inheritDoc} */
128     public String toString() {
129         return delegate.toString();
130     }
131 
132     /** {@inheritDoc} */
133     public int hashCode() {
134         return delegate.hashCode();
135     }
136 
137     /** {@inheritDoc} */
138     public boolean equals(Object obj) {
139         if (this == obj) {
140             return true;
141         }
142 
143         if (obj == null || this.getClass() != obj.getClass()) {
144             return false;
145         }
146 
147         return delegate.equals(((LazyMap<?, ?>) obj).delegate);
148     }
149 }