1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.kernel.cache;
24  
25  import com.liferay.portal.kernel.concurrent.CompeteLatch;
26  
27  import java.io.Serializable;
28  
29  import java.util.concurrent.ConcurrentHashMap;
30  import java.util.concurrent.ConcurrentMap;
31  
32  /**
33   * <a href="BlockingPortalCache.java.html"><b><i>View Source</i></b></a>
34   *
35   * @author Shuyang Zhou
36   */
37  public class BlockingPortalCache implements PortalCache {
38  
39      public BlockingPortalCache(PortalCache portalCache) {
40          _portalCache = portalCache;
41      }
42  
43      public Object get(String key) {
44          Object obj = _portalCache.get(key);
45  
46          if (obj != null) {
47              return obj;
48          }
49  
50          CompeteLatch lastCompeteLatch = _competeLatch.get();
51  
52          if (lastCompeteLatch != null) {
53              lastCompeteLatch.done();
54  
55              _competeLatch.set(null);
56          }
57  
58          CompeteLatch currentCompeteLatch = _competeLatchMap.get(key);
59  
60          if (currentCompeteLatch == null) {
61              CompeteLatch newCompeteLatch = new CompeteLatch();
62  
63              currentCompeteLatch = _competeLatchMap.putIfAbsent(
64                  key, newCompeteLatch);
65  
66              if (currentCompeteLatch == null) {
67                  currentCompeteLatch = newCompeteLatch;
68              }
69          }
70  
71          _competeLatch.set(currentCompeteLatch);
72  
73          if (!currentCompeteLatch.compete()) {
74              currentCompeteLatch.await();
75  
76              _competeLatch.set(null);
77  
78              obj = _portalCache.get(key);
79          }
80  
81          return obj;
82      }
83  
84      public void put(String key, Object obj) {
85          if (key == null) {
86              throw new IllegalArgumentException("Key is null");
87          }
88  
89          if (obj == null) {
90              throw new IllegalArgumentException("Object is null");
91          }
92  
93          _portalCache.put(key, obj);
94  
95          CompeteLatch competeLatch = _competeLatch.get();
96  
97          if (competeLatch != null) {
98              competeLatch.done();
99  
100             _competeLatch.set(null);
101         }
102 
103         _competeLatchMap.remove(key);
104     }
105 
106     public void put(String key, Object obj, int timeToLive) {
107         if (key == null) {
108             throw new IllegalArgumentException("Key is null");
109         }
110 
111         if (obj == null) {
112             throw new IllegalArgumentException("Object is null");
113         }
114 
115         _portalCache.put(key, obj, timeToLive);
116 
117         CompeteLatch competeLatch = _competeLatch.get();
118 
119         if (competeLatch != null) {
120             competeLatch.done();
121 
122             _competeLatch.set(null);
123         }
124 
125         _competeLatchMap.remove(key);
126     }
127 
128     public void put(String key, Serializable obj) {
129         if (key == null) {
130             throw new IllegalArgumentException("Key is null");
131         }
132 
133         if (obj == null) {
134             throw new IllegalArgumentException("Object is null");
135         }
136 
137         _portalCache.put(key, obj);
138 
139         CompeteLatch competeLatch = _competeLatch.get();
140 
141         if (competeLatch != null) {
142             competeLatch.done();
143 
144             _competeLatch.set(null);
145         }
146 
147         _competeLatchMap.remove(key);
148     }
149 
150     public void put(String key, Serializable obj, int timeToLive) {
151         if (key == null) {
152             throw new IllegalArgumentException("Key is null");
153         }
154 
155         if (obj == null) {
156             throw new IllegalArgumentException("Object is null");
157         }
158 
159         _portalCache.put(key, obj, timeToLive);
160 
161         CompeteLatch competeLatch = _competeLatch.get();
162 
163         if (competeLatch != null) {
164             competeLatch.done();
165 
166             _competeLatch.set(null);
167         }
168 
169         _competeLatchMap.remove(key);
170     }
171 
172     public void remove(String key) {
173         _portalCache.remove(key);
174         _competeLatchMap.remove(key);
175     }
176 
177     public void removeAll() {
178         _portalCache.removeAll();
179         _competeLatchMap.clear();
180     }
181 
182     private static ThreadLocal<CompeteLatch> _competeLatch =
183         new ThreadLocal<CompeteLatch>();
184     private final ConcurrentMap<String, CompeteLatch> _competeLatchMap =
185         new ConcurrentHashMap<String, CompeteLatch>();
186     private final PortalCache _portalCache;
187 
188 }