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.cache.memcached;
16  
17  import com.liferay.portal.kernel.cache.BasePortalCache;
18  import com.liferay.portal.kernel.log.Log;
19  import com.liferay.portal.kernel.log.LogFactoryUtil;
20  
21  import java.io.Serializable;
22  
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.concurrent.Future;
28  import java.util.concurrent.TimeUnit;
29  
30  import net.spy.memcached.MemcachedClientIF;
31  
32  /**
33   * <a href="MemcachePortalCache.java.html"><b><i>View Source</i></b></a>
34   *
35   * @author Michael C. Han
36   */
37  public class MemcachePortalCache extends BasePortalCache {
38  
39      public MemcachePortalCache(
40          String name, MemcachedClientIF memcachedClient, int timeout,
41          TimeUnit timeoutTimeUnit) {
42  
43          _name = name;
44          _memcachedClient = memcachedClient;
45          _timeout = timeout;
46          _timeoutTimeUnit = timeoutTimeUnit;
47      }
48  
49      public void destroy() {
50          _memcachedClient.shutdown();
51      }
52  
53      public Collection<Object> get(Collection<String> keys) {
54          List<String> processedKeys = new ArrayList<String>(keys.size());
55  
56          for (String key : keys) {
57              String processedKey = processKey(_name.concat(key));
58  
59              processedKeys.add(processedKey);
60          }
61  
62          Future<Map<String,Object>> future = null;
63  
64          try {
65              future = _memcachedClient.asyncGetBulk(processedKeys);
66          }
67          catch (IllegalArgumentException iae) {
68              if (_log.isWarnEnabled()) {
69                  _log.warn("Error retrieving with keys " + keys, iae);
70              }
71  
72              return null;
73          }
74  
75          Map<String, Object> values = null;
76  
77          try {
78              values = future.get(_timeout, _timeoutTimeUnit);
79          }
80          catch (Throwable t) {
81              if (_log.isWarnEnabled()) {
82                  _log.warn("Memcache operation error", t);
83              }
84  
85              future.cancel(true);
86          }
87  
88          return values.values();
89      }
90  
91      public Object get(String key) {
92          String processedKey = processKey(_name.concat(key));
93  
94          Future<Object> future = null;
95  
96          try {
97              future = _memcachedClient.asyncGet(processedKey);
98          }
99          catch (IllegalArgumentException iae) {
100             if (_log.isWarnEnabled()) {
101                 _log.warn("Error retrieving with key " + key, iae);
102             }
103 
104             return null;
105         }
106 
107         Object value = null;
108 
109         try {
110             value = future.get(_timeout, _timeoutTimeUnit);
111         }
112         catch (Throwable t) {
113             if (_log.isWarnEnabled()) {
114                 _log.warn("Memcache operation error", t);
115             }
116 
117             future.cancel(true);
118         }
119 
120         return value;
121     }
122 
123     public void put(String key, Object obj) {
124         put(key, obj, _timeToLive);
125     }
126 
127     public void put(String key, Object obj, int timeToLive) {
128         String processedKey = processKey(_name.concat(key));
129 
130         try {
131             _memcachedClient.set(processedKey, timeToLive, obj);
132         }
133         catch (IllegalArgumentException iae) {
134             if (_log.isWarnEnabled()) {
135                 _log.warn("Error storing value with key " + key, iae);
136             }
137         }
138     }
139 
140     public void put(String key, Serializable obj) {
141         put(key, obj, _timeToLive);
142     }
143 
144     public void put(String key, Serializable obj, int timeToLive) {
145         String processedKey = processKey(_name.concat(key));
146 
147         try {
148             _memcachedClient.set(processedKey, timeToLive, obj);
149         }
150         catch (IllegalArgumentException iae) {
151             if (_log.isWarnEnabled()) {
152                 _log.warn("Error storing value with key " + key, iae);
153             }
154         }
155     }
156 
157     public void remove(String key) {
158         String processedKey = processKey(_name.concat(key));
159 
160         try {
161             _memcachedClient.delete(processedKey);
162         }
163         catch (IllegalArgumentException iae) {
164             if (_log.isWarnEnabled()) {
165                 _log.warn("Error removing value with key " + key, iae);
166             }
167         }
168     }
169 
170     public void removeAll() {
171         _memcachedClient.flush();
172     }
173 
174     public void setTimeToLive(int timeToLive) {
175         _timeToLive = timeToLive;
176     }
177 
178     private static final Log _log = LogFactoryUtil.getLog(
179         MemcachePortalCache.class);
180 
181     private MemcachedClientIF _memcachedClient;
182     private String _name;
183     private int _timeout;
184     private TimeUnit _timeoutTimeUnit;
185     private int _timeToLive;
186 
187 }