001    /**
002     * Copyright (c) 2000-present 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.ehcache;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.InstanceFactory;
020    import com.liferay.portal.util.PropsValues;
021    
022    import java.util.List;
023    import java.util.Properties;
024    
025    import net.sf.ehcache.CacheException;
026    import net.sf.ehcache.CacheManager;
027    import net.sf.ehcache.Ehcache;
028    import net.sf.ehcache.Element;
029    import net.sf.ehcache.Status;
030    import net.sf.ehcache.distribution.CacheManagerPeerListener;
031    import net.sf.ehcache.distribution.CacheManagerPeerListenerFactory;
032    import net.sf.ehcache.distribution.CacheReplicator;
033    import net.sf.ehcache.event.RegisteredEventListeners;
034    
035    /**
036     * @author Tina Tian
037     */
038    public class LiferayCacheManagerPeerListenerFactory
039            extends CacheManagerPeerListenerFactory {
040    
041            public LiferayCacheManagerPeerListenerFactory() {
042                    String className =
043                            PropsValues.EHCACHE_CACHE_MANAGER_PEER_LISTENER_FACTORY;
044    
045                    if (_log.isDebugEnabled()) {
046                            _log.debug("Instantiating " + className + " " + hashCode());
047                    }
048    
049                    try {
050                            _cacheManagerPeerListenerFactory =
051                                    (CacheManagerPeerListenerFactory)InstanceFactory.newInstance(
052                                            className);
053                    }
054                    catch (Exception e) {
055                            throw new RuntimeException(e);
056                    }
057            }
058    
059            @Override
060            public CacheManagerPeerListener createCachePeerListener(
061                    CacheManager cacheManager, Properties properties) {
062    
063                    CacheManagerPeerListener cacheManagerPeerListener =
064                            _cacheManagerPeerListenerFactory.createCachePeerListener(
065                                    cacheManager, properties);
066    
067                    if (PropsValues.CLUSTER_LINK_ENABLED &&
068                            !PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED) {
069    
070                            return new LiferayCacheManagerPeerListener(
071                                    cacheManager, cacheManagerPeerListener);
072                    }
073    
074                    return cacheManagerPeerListener;
075            }
076    
077            private static final CacheReplicator _PLACE_HOLDER =
078                    new CacheReplicator() {
079    
080                            @Override
081                            public boolean alive() {
082                                    return true;
083                            }
084    
085                            @Override
086                            public Object clone() {
087                                    return this;
088                            }
089    
090                            @Override
091                            public void dispose() {
092                            }
093    
094                            @Override
095                            public boolean isReplicateUpdatesViaCopy() {
096                                    return false;
097                            }
098    
099                            @Override
100                            public boolean notAlive() {
101                                    return false;
102                            }
103    
104                            @Override
105                            public void notifyElementEvicted(Ehcache ehcache, Element element) {
106                            }
107    
108                            @Override
109                            public void notifyElementExpired(Ehcache ehcache, Element element) {
110                            }
111    
112                            @Override
113                            public void notifyElementPut(Ehcache ehcache, Element element) {
114                            }
115    
116                            @Override
117                            public void notifyElementRemoved(Ehcache ehcache, Element element) {
118                            }
119    
120                            @Override
121                            public void notifyElementUpdated(Ehcache ehcache, Element element) {
122                            }
123    
124                            @Override
125                            public void notifyRemoveAll(Ehcache ehch) {
126                            }
127    
128                    };
129    
130            private static final Log _log = LogFactoryUtil.getLog(
131                    LiferayCacheManagerPeerListenerFactory.class);
132    
133            private final CacheManagerPeerListenerFactory
134                    _cacheManagerPeerListenerFactory;
135    
136            private static class LiferayCacheManagerPeerListener
137                    implements CacheManagerPeerListener {
138    
139                    public LiferayCacheManagerPeerListener(
140                            CacheManager cacheManager,
141                            CacheManagerPeerListener cacheManagerPeerListener) {
142    
143                            _cacheManager = cacheManager;
144                            _cacheManagerPeerListener = cacheManagerPeerListener;
145                    }
146    
147                    @Override
148                    public void attemptResolutionOfUniqueResourceConflict()
149                            throws CacheException, IllegalStateException {
150    
151                            _cacheManagerPeerListener.
152                                    attemptResolutionOfUniqueResourceConflict();
153                    }
154    
155                    @Override
156                    public void dispose() {
157                            _cacheManagerPeerListener.dispose();
158                    }
159    
160                    @Override
161                    @SuppressWarnings("rawtypes")
162                    public List getBoundCachePeers() {
163                            return _cacheManagerPeerListener.getBoundCachePeers();
164                    }
165    
166                    @Override
167                    public String getScheme() {
168                            return _cacheManagerPeerListener.getScheme();
169                    }
170    
171                    @Override
172                    public Status getStatus() {
173                            return _cacheManagerPeerListener.getStatus();
174                    }
175    
176                    @Override
177                    public String getUniqueResourceIdentifier() {
178                            return _cacheManagerPeerListener.getUniqueResourceIdentifier();
179                    }
180    
181                    @Override
182                    public void init() {
183                            for (String cacheName : _cacheManager.getCacheNames()) {
184                                    _wrapEhcache(cacheName);
185                            }
186    
187                            try {
188                                    _cacheManagerPeerListener.init();
189                            }
190                            finally {
191                                    for (String cacheName : _cacheManager.getCacheNames()) {
192                                            _unwrapEhcache(cacheName);
193                                    }
194                            }
195                    }
196    
197                    @Override
198                    public void notifyCacheAdded(String cacheName) {
199                            _wrapEhcache(cacheName);
200    
201                            try {
202                                    _cacheManagerPeerListener.notifyCacheAdded(cacheName);
203                            }
204                            finally {
205                                    _unwrapEhcache(cacheName);
206                            }
207                    }
208    
209                    @Override
210                    public void notifyCacheRemoved(String cacheName) {
211                            _cacheManagerPeerListener.notifyCacheRemoved(cacheName);
212                    }
213    
214                    private void _unwrapEhcache(String cacheName) {
215                            Ehcache ehcache = _cacheManager.getEhcache(cacheName);
216    
217                            if (!(ehcache instanceof LiferayCacheDecorator)) {
218                                    return;
219                            }
220    
221                            LiferayCacheDecorator liferayCacheDecorator =
222                                    (LiferayCacheDecorator)ehcache;
223    
224                            _cacheManager.replaceCacheWithDecoratedCache(
225                                    liferayCacheDecorator,
226                                    liferayCacheDecorator.getUnderlyingCache());
227    
228                            RegisteredEventListeners registeredEventListeners =
229                                    ehcache.getCacheEventNotificationService();
230    
231                            registeredEventListeners.unregisterListener(_PLACE_HOLDER);
232                    }
233    
234                    private void _wrapEhcache(String cacheName) {
235                            Ehcache ehcache = _cacheManager.getEhcache(cacheName);
236    
237                            if (!(ehcache instanceof LiferayCacheDecorator)) {
238                                    _cacheManager.replaceCacheWithDecoratedCache(
239                                            ehcache, new LiferayCacheDecorator(ehcache));
240                            }
241    
242                            RegisteredEventListeners registeredEventListeners =
243                                    ehcache.getCacheEventNotificationService();
244    
245                            registeredEventListeners.registerListener(_PLACE_HOLDER);
246                    }
247    
248                    private final CacheManager _cacheManager;
249                    private final CacheManagerPeerListener _cacheManagerPeerListener;
250    
251            }
252    
253    }