001    /**
002     * Copyright (c) 2000-2013 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.cache.cluster.EhcachePortalCacheClusterReplicatorFactory;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.Validator;
020    import com.liferay.portal.util.PropsUtil;
021    import com.liferay.portal.util.PropsValues;
022    
023    import java.net.URL;
024    
025    import java.util.List;
026    import java.util.Map;
027    
028    import net.sf.ehcache.config.CacheConfiguration;
029    import net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
030    import net.sf.ehcache.config.Configuration;
031    import net.sf.ehcache.config.ConfigurationFactory;
032    
033    /**
034     * @author Shuyang Zhou
035     * @author Edward Han
036     */
037    public class EhcacheConfigurationUtil {
038    
039            public static final boolean EHCACHE_BOOTSTRAP_CACHE_LOADER_ENABLED =
040                    GetterUtil.getBoolean(
041                            PropsUtil.get("ehcache.bootstrap.cache.loader.enabled"));
042    
043            public static Configuration getConfiguration(String configurationPath) {
044                    return getConfiguration(configurationPath, false);
045            }
046    
047            public static Configuration getConfiguration(
048                    String configurationPath, boolean clusterAware) {
049    
050                    return getConfiguration(configurationPath, clusterAware, false);
051            }
052    
053            public static Configuration getConfiguration(
054                    String configurationPath, boolean clusterAware, boolean usingDefault) {
055    
056                    if (Validator.isNull(configurationPath)) {
057                            return null;
058                    }
059    
060                    URL configurationURL = EhcacheConfigurationUtil.class.getResource(
061                            configurationPath);
062    
063                    return getConfiguration(configurationURL, clusterAware, usingDefault);
064            }
065    
066            public static Configuration getConfiguration(URL configurationURL) {
067                    return getConfiguration(configurationURL, false);
068            }
069    
070            public static Configuration getConfiguration(
071                    URL configurationURL, boolean clusterAware) {
072    
073                    return getConfiguration(configurationURL, clusterAware, false);
074            }
075    
076            public static Configuration getConfiguration(
077                    URL configurationURL, boolean clusterAware, boolean usingDefault) {
078    
079                    if (Validator.isNull(configurationURL)) {
080                            return null;
081                    }
082    
083                    Configuration configuration = ConfigurationFactory.parseConfiguration(
084                            configurationURL);
085    
086                    boolean enableClusterLinkReplication = false;
087    
088                    if (PropsValues.CLUSTER_LINK_ENABLED &&
089                            PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED) {
090    
091                            enableClusterLinkReplication = true;
092                    }
093    
094                    if (clusterAware && (usingDefault || enableClusterLinkReplication)) {
095                            return _processDefaultClusterLinkReplication(
096                                    configuration, usingDefault, enableClusterLinkReplication);
097                    }
098    
099                    return configuration;
100            }
101    
102            private static String _clearCacheEventListenerConfigurations(
103                    CacheConfiguration cacheConfiguration) {
104    
105                    List<?> cacheEventListenerConfigurations =
106                            cacheConfiguration.getCacheEventListenerConfigurations();
107    
108                    String cacheEventListenerProperties = null;
109    
110                    for (Object cacheEventListenerConfiguration :
111                                    cacheEventListenerConfigurations) {
112    
113                            CacheEventListenerFactoryConfiguration
114                                    cacheEventListenerFactoryConfiguration =
115                                            (CacheEventListenerFactoryConfiguration)
116                                                    cacheEventListenerConfiguration;
117    
118                            String fullyQualifiedClassPath =
119                                    cacheEventListenerFactoryConfiguration.
120                                            getFullyQualifiedClassPath();
121    
122                            if (fullyQualifiedClassPath.contains(
123                                            "LiferayCacheEventListenerFactory") ||
124                                    fullyQualifiedClassPath.contains(
125                                            "net.sf.ehcache.distribution")) {
126    
127                                    cacheEventListenerProperties =
128                                            cacheEventListenerFactoryConfiguration.getProperties();
129    
130                                    break;
131                            }
132                    }
133    
134                    cacheEventListenerConfigurations.clear();
135    
136                    return cacheEventListenerProperties;
137            }
138    
139            private static void _configureCacheEventListeners(
140                    boolean enableClusterLinkReplication,
141                    boolean clearCachePeerProviderConfigurations, boolean usingDefault,
142                    CacheConfiguration cacheConfiguration) {
143    
144                    if (cacheConfiguration == null) {
145                            return;
146                    }
147    
148                    if (!EHCACHE_BOOTSTRAP_CACHE_LOADER_ENABLED) {
149                            cacheConfiguration.addBootstrapCacheLoaderFactory(null);
150                    }
151    
152                    List<CacheEventListenerFactoryConfiguration>
153                            cacheEventListenerFactoryConfigurations =
154                                    cacheConfiguration.getCacheEventListenerConfigurations();
155    
156                    boolean usingLiferayCacheEventListenerFactory = false;
157    
158                    for (CacheEventListenerFactoryConfiguration
159                                    cacheEventListenerFactoryConfiguration :
160                                            cacheEventListenerFactoryConfigurations) {
161    
162                            String className =
163                                    cacheEventListenerFactoryConfiguration.
164                                            getFullyQualifiedClassPath();
165    
166                            if (className.equals(
167                                            LiferayCacheEventListenerFactory.class.getName())) {
168    
169                                    usingLiferayCacheEventListenerFactory = true;
170    
171                                    break;
172                            }
173                    }
174    
175                    if (clearCachePeerProviderConfigurations ||
176                            (!usingDefault && usingLiferayCacheEventListenerFactory)) {
177    
178                            String cacheEventListenerProperties =
179                                    _clearCacheEventListenerConfigurations(cacheConfiguration);
180    
181                            if (enableClusterLinkReplication) {
182                                    _enableClusterLinkReplication(
183                                            cacheConfiguration, cacheEventListenerProperties);
184                            }
185                    }
186            }
187    
188            private static void _enableClusterLinkReplication(
189                    CacheConfiguration cacheConfiguration,
190                    String cacheEventListenerProperties) {
191    
192                    CacheEventListenerFactoryConfiguration
193                            cacheEventListenerFactoryConfiguration =
194                                    new CacheEventListenerFactoryConfiguration();
195    
196                    cacheEventListenerFactoryConfiguration.setClass(
197                            EhcachePortalCacheClusterReplicatorFactory.class.getName());
198                    cacheEventListenerFactoryConfiguration.setProperties(
199                            cacheEventListenerProperties);
200    
201                    cacheConfiguration.addCacheEventListenerFactory(
202                            cacheEventListenerFactoryConfiguration);
203            }
204    
205            private static Configuration _processDefaultClusterLinkReplication(
206                    Configuration configuration, boolean usingDefault,
207                    boolean enableClusterLinkReplication) {
208    
209                    boolean clearCachePeerProviderConfigurations = false;
210    
211                    if ((enableClusterLinkReplication) ||
212                            (usingDefault && !PropsValues.CLUSTER_LINK_ENABLED)) {
213    
214                            clearCachePeerProviderConfigurations = true;
215                    }
216    
217                    if (clearCachePeerProviderConfigurations) {
218                            configuration.getCacheManagerPeerListenerFactoryConfigurations().
219                                    clear();
220                            configuration.getCacheManagerPeerProviderFactoryConfiguration().
221                                    clear();
222                    }
223    
224                    CacheConfiguration defaultCacheConfiguration =
225                            configuration.getDefaultCacheConfiguration();
226    
227                    _configureCacheEventListeners(
228                            enableClusterLinkReplication, clearCachePeerProviderConfigurations,
229                            usingDefault, defaultCacheConfiguration);
230    
231                    Map<String, CacheConfiguration> cacheConfigurations =
232                            configuration.getCacheConfigurations();
233    
234                    for (CacheConfiguration cacheConfiguration :
235                                    cacheConfigurations.values()) {
236    
237                            _configureCacheEventListeners(
238                                    enableClusterLinkReplication,
239                                    clearCachePeerProviderConfigurations, usingDefault,
240                                    cacheConfiguration);
241                    }
242    
243                    return configuration;
244            }
245    
246    }