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.concurrent.ConcurrentHashMap;
22  import java.util.concurrent.ConcurrentMap;
23  
24  /**
25   * <a href="BlockingPortalCache.java.html"><b><i>View Source</i></b></a>
26   *
27   * @author Shuyang Zhou
28   */
29  public class BlockingPortalCache implements PortalCache {
30  
31      public BlockingPortalCache(PortalCache portalCache) {
32          _portalCache = portalCache;
33      }
34  
35      public Object get(String key) {
36          Object obj = _portalCache.get(key);
37  
38          if (obj != null) {
39              return obj;
40          }
41  
42          CompeteLatch lastCompeteLatch = _competeLatch.get();
43  
44          if (lastCompeteLatch != null) {
45              lastCompeteLatch.done();
46  
47              _competeLatch.set(null);
48          }
49  
50          CompeteLatch currentCompeteLatch = _competeLatchMap.get(key);
51  
52          if (currentCompeteLatch == null) {
53              CompeteLatch newCompeteLatch = new CompeteLatch();
54  
55              currentCompeteLatch = _competeLatchMap.putIfAbsent(
56                  key, newCompeteLatch);
57  
58              if (currentCompeteLatch == null) {
59                  currentCompeteLatch = newCompeteLatch;
60              }
61          }
62  
63          _competeLatch.set(currentCompeteLatch);
64  
65          if (!currentCompeteLatch.compete()) {
66              currentCompeteLatch.await();
67  
68              _competeLatch.set(null);
69  
70              obj = _portalCache.get(key);
71          }
72  
73          return obj;
74      }
75  
76      public void put(String key, Object obj) {
77          if (key == null) {
78              throw new IllegalArgumentException("Key is null");
79          }
80  
81          if (obj == null) {
82              throw new IllegalArgumentException("Object is null");
83          }
84  
85          _portalCache.put(key, obj);
86  
87          CompeteLatch competeLatch = _competeLatch.get();
88  
89          if (competeLatch != null) {
90              competeLatch.done();
91  
92              _competeLatch.set(null);
93          }
94  
95          _competeLatchMap.remove(key);
96      }
97  
98      public void put(String key, Object obj, int timeToLive) {
99          if (key == null) {
100             throw new IllegalArgumentException("Key is null");
101         }
102 
103         if (obj == null) {
104             throw new IllegalArgumentException("Object is null");
105         }
106 
107         _portalCache.put(key, obj, timeToLive);
108 
109         CompeteLatch competeLatch = _competeLatch.get();
110 
111         if (competeLatch != null) {
112             competeLatch.done();
113 
114             _competeLatch.set(null);
115         }
116 
117         _competeLatchMap.remove(key);
118     }
119 
120     public void put(String key, Serializable obj) {
121         if (key == null) {
122             throw new IllegalArgumentException("Key is null");
123         }
124 
125         if (obj == null) {
126             throw new IllegalArgumentException("Object is null");
127         }
128 
129         _portalCache.put(key, obj);
130 
131         CompeteLatch competeLatch = _competeLatch.get();
132 
133         if (competeLatch != null) {
134             competeLatch.done();
135 
136             _competeLatch.set(null);
137         }
138 
139         _competeLatchMap.remove(key);
140     }
141 
142     public void put(String key, Serializable obj, int timeToLive) {
143         if (key == null) {
144             throw new IllegalArgumentException("Key is null");
145         }
146 
147         if (obj == null) {
148             throw new IllegalArgumentException("Object is null");
149         }
150 
151         _portalCache.put(key, obj, timeToLive);
152 
153         CompeteLatch competeLatch = _competeLatch.get();
154 
155         if (competeLatch != null) {
156             competeLatch.done();
157 
158             _competeLatch.set(null);
159         }
160 
161         _competeLatchMap.remove(key);
162     }
163 
164     public void remove(String key) {
165         _portalCache.remove(key);
166         _competeLatchMap.remove(key);
167     }
168 
169     public void removeAll() {
170         _portalCache.removeAll();
171         _competeLatchMap.clear();
172     }
173 
174     private static ThreadLocal<CompeteLatch> _competeLatch =
175         new ThreadLocal<CompeteLatch>();
176     private final ConcurrentMap<String, CompeteLatch> _competeLatchMap =
177         new ConcurrentHashMap<String, CompeteLatch>();
178     private final PortalCache _portalCache;
179 
180 }