001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.cache.memcached;
016    
017    import com.liferay.portal.kernel.cache.BasePortalCache;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    
021    import java.io.Serializable;
022    
023    import java.util.ArrayList;
024    import java.util.Collection;
025    import java.util.List;
026    import java.util.Map;
027    import java.util.concurrent.Future;
028    import java.util.concurrent.TimeUnit;
029    
030    import net.spy.memcached.MemcachedClientIF;
031    
032    /**
033     * @author Michael C. Han
034     */
035    public class MemcachePortalCache extends BasePortalCache {
036    
037            public MemcachePortalCache(
038                    String name, MemcachedClientIF memcachedClient, int timeout,
039                    TimeUnit timeoutTimeUnit) {
040    
041                    _name = name;
042                    _memcachedClient = memcachedClient;
043                    _timeout = timeout;
044                    _timeoutTimeUnit = timeoutTimeUnit;
045            }
046    
047            public void destroy() {
048                    _memcachedClient.shutdown();
049            }
050    
051            public Collection<Object> get(Collection<String> keys) {
052                    List<String> processedKeys = new ArrayList<String>(keys.size());
053    
054                    for (String key : keys) {
055                            String processedKey = processKey(_name.concat(key));
056    
057                            processedKeys.add(processedKey);
058                    }
059    
060                    Future<Map<String,Object>> future = null;
061    
062                    try {
063                            future = _memcachedClient.asyncGetBulk(processedKeys);
064                    }
065                    catch (IllegalArgumentException iae) {
066                            if (_log.isWarnEnabled()) {
067                                    _log.warn("Error retrieving with keys " + keys, iae);
068                            }
069    
070                            return null;
071                    }
072    
073                    Map<String, Object> values = null;
074    
075                    try {
076                            values = future.get(_timeout, _timeoutTimeUnit);
077                    }
078                    catch (Throwable t) {
079                            if (_log.isWarnEnabled()) {
080                                    _log.warn("Memcache operation error", t);
081                            }
082    
083                            future.cancel(true);
084                    }
085    
086                    return values.values();
087            }
088    
089            public Object get(String key) {
090                    String processedKey = processKey(_name.concat(key));
091    
092                    Future<Object> future = null;
093    
094                    try {
095                            future = _memcachedClient.asyncGet(processedKey);
096                    }
097                    catch (IllegalArgumentException iae) {
098                            if (_log.isWarnEnabled()) {
099                                    _log.warn("Error retrieving with key " + key, iae);
100                            }
101    
102                            return null;
103                    }
104    
105                    Object value = null;
106    
107                    try {
108                            value = future.get(_timeout, _timeoutTimeUnit);
109                    }
110                    catch (Throwable t) {
111                            if (_log.isWarnEnabled()) {
112                                    _log.warn("Memcache operation error", t);
113                            }
114    
115                            future.cancel(true);
116                    }
117    
118                    return value;
119            }
120    
121            public void put(String key, Object obj) {
122                    put(key, obj, _timeToLive);
123            }
124    
125            public void put(String key, Object obj, int timeToLive) {
126                    String processedKey = processKey(_name.concat(key));
127    
128                    try {
129                            _memcachedClient.set(processedKey, timeToLive, obj);
130                    }
131                    catch (IllegalArgumentException iae) {
132                            if (_log.isWarnEnabled()) {
133                                    _log.warn("Error storing value with key " + key, iae);
134                            }
135                    }
136            }
137    
138            public void put(String key, Serializable obj) {
139                    put(key, obj, _timeToLive);
140            }
141    
142            public void put(String key, Serializable obj, int timeToLive) {
143                    String processedKey = processKey(_name.concat(key));
144    
145                    try {
146                            _memcachedClient.set(processedKey, timeToLive, obj);
147                    }
148                    catch (IllegalArgumentException iae) {
149                            if (_log.isWarnEnabled()) {
150                                    _log.warn("Error storing value with key " + key, iae);
151                            }
152                    }
153            }
154    
155            public void remove(String key) {
156                    String processedKey = processKey(_name.concat(key));
157    
158                    try {
159                            _memcachedClient.delete(processedKey);
160                    }
161                    catch (IllegalArgumentException iae) {
162                            if (_log.isWarnEnabled()) {
163                                    _log.warn("Error removing value with key " + key, iae);
164                            }
165                    }
166            }
167    
168            public void removeAll() {
169                    _memcachedClient.flush();
170            }
171    
172            public void setTimeToLive(int timeToLive) {
173                    _timeToLive = timeToLive;
174            }
175    
176            private static final Log _log = LogFactoryUtil.getLog(
177                    MemcachePortalCache.class);
178    
179            private MemcachedClientIF _memcachedClient;
180            private String _name;
181            private int _timeout;
182            private TimeUnit _timeoutTimeUnit;
183            private int _timeToLive;
184    
185    }