1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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              try {
75                  currentCompeteLatch.await();
76              }
77              catch (InterruptedException ie) {
78              }
79  
80              _competeLatch.set(null);
81  
82              obj = _portalCache.get(key);
83          }
84  
85          return obj;
86      }
87  
88      public void put(String key, Object obj) {
89          if (key == null) {
90              throw new IllegalArgumentException("Key is null");
91          }
92  
93          if (obj == null) {
94              throw new IllegalArgumentException("Object is null");
95          }
96  
97          _portalCache.put(key, obj);
98  
99          CompeteLatch competeLatch = _competeLatch.get();
100 
101         if (competeLatch != null) {
102             competeLatch.done();
103 
104             _competeLatch.set(null);
105         }
106 
107         _competeLatchMap.remove(key);
108     }
109 
110     public void put(String key, Object obj, int timeToLive) {
111         if (key == null) {
112             throw new IllegalArgumentException("Key is null");
113         }
114 
115         if (obj == null) {
116             throw new IllegalArgumentException("Object is null");
117         }
118 
119         _portalCache.put(key, obj, timeToLive);
120 
121         CompeteLatch competeLatch = _competeLatch.get();
122 
123         if (competeLatch != null) {
124             competeLatch.done();
125 
126             _competeLatch.set(null);
127         }
128 
129         _competeLatchMap.remove(key);
130     }
131 
132     public void put(String key, Serializable obj) {
133         if (key == null) {
134             throw new IllegalArgumentException("Key is null");
135         }
136 
137         if (obj == null) {
138             throw new IllegalArgumentException("Object is null");
139         }
140 
141         _portalCache.put(key, obj);
142 
143         CompeteLatch competeLatch = _competeLatch.get();
144 
145         if (competeLatch != null) {
146             competeLatch.done();
147 
148             _competeLatch.set(null);
149         }
150 
151         _competeLatchMap.remove(key);
152     }
153 
154     public void put(String key, Serializable obj, int timeToLive) {
155         if (key == null) {
156             throw new IllegalArgumentException("Key is null");
157         }
158 
159         if (obj == null) {
160             throw new IllegalArgumentException("Object is null");
161         }
162 
163         _portalCache.put(key, obj, timeToLive);
164 
165         CompeteLatch competeLatch = _competeLatch.get();
166 
167         if (competeLatch != null) {
168             competeLatch.done();
169 
170             _competeLatch.set(null);
171         }
172 
173         _competeLatchMap.remove(key);
174     }
175 
176     public void remove(String key) {
177         _portalCache.remove(key);
178         _competeLatchMap.remove(key);
179     }
180 
181     public void removeAll() {
182         _portalCache.removeAll();
183         _competeLatchMap.clear();
184     }
185 
186     public void setDebug(boolean debug) {
187         _portalCache.setDebug(debug);
188     }
189 
190     private static ThreadLocal<CompeteLatch> _competeLatch =
191         new ThreadLocal<CompeteLatch>();
192     private final ConcurrentMap<String, CompeteLatch> _competeLatchMap =
193         new ConcurrentHashMap<String, CompeteLatch>();
194     private final PortalCache _portalCache;
195 
196 }