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> map) {
91          if(map == null || map.isEmpty()){
92              return;
93          }
94          
95          delegate = buildMap();
96          delegate.putAll(map);
97      }
98  
99      /** {@inheritDoc} */
100     public ValueType remove(Object key) {
101         delegate = buildMap();
102         return delegate.remove(key);
103     }
104 
105     /** {@inheritDoc} */
106     public int size() {
107         return delegate.size();
108     }
109 
110     /** {@inheritDoc} */
111     public Collection<ValueType> values() {
112         return delegate.values();
113     }
114 
115     /**
116      * Builds an appropriate delegate map.
117      * 
118      * @return the delegate map
119      */
120     protected Map<KeyType, ValueType> buildMap() {
121         if (delegate instanceof HashMap) {
122             return delegate;
123         }
124 
125         return new HashMap<KeyType, ValueType>(delegate);
126     }
127 }