1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.kernel.cache;
16  
17  import com.liferay.portal.kernel.concurrent.CompeteLatch;
18  
19  import java.io.Serializable;
20  
21  import java.util.Collection;
22  import java.util.concurrent.ConcurrentHashMap;
23  import java.util.concurrent.ConcurrentMap;
24  
25  /**
26   * <a href="BlockingPortalCache.java.html"><b><i>View Source</i></b></a>
27   *
28   * @author Shuyang Zhou
29   */
30  public class BlockingPortalCache implements PortalCache {
31  
32      public BlockingPortalCache(PortalCache portalCache) {
33          _portalCache = portalCache;
34      }
35  
36      public void destroy() {
37      }
38  
39      public Collection<Object> get(Collection<String> keys) {
40          return _portalCache.get(keys);
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     public void setDebug(boolean debug) {
183         _portalCache.setDebug(debug);
184     }
185 
186     private static ThreadLocal<CompeteLatch> _competeLatch =
187         new ThreadLocal<CompeteLatch>();
188     private final ConcurrentMap<String, CompeteLatch> _competeLatchMap =
189         new ConcurrentHashMap<String, CompeteLatch>();
190     private final PortalCache _portalCache;
191 
192 }