001
014
015 package com.liferay.portal.cache.ehcache;
016
017 import com.liferay.portal.cache.cluster.ClusterLinkCallbackFactory;
018 import com.liferay.portal.kernel.cache.CacheListenerScope;
019 import com.liferay.portal.kernel.cache.configuration.CallbackConfiguration;
020 import com.liferay.portal.kernel.cache.configuration.PortalCacheConfiguration;
021 import com.liferay.portal.kernel.cache.configuration.PortalCacheManagerConfiguration;
022 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
023 import com.liferay.portal.kernel.util.ObjectValuePair;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.util.PropsValues;
027
028 import java.io.IOException;
029
030 import java.net.URL;
031
032 import java.util.Collections;
033 import java.util.HashMap;
034 import java.util.HashSet;
035 import java.util.List;
036 import java.util.Map;
037 import java.util.Properties;
038 import java.util.Set;
039
040 import net.sf.ehcache.config.CacheConfiguration;
041 import net.sf.ehcache.config.CacheConfiguration.BootstrapCacheLoaderFactoryConfiguration;
042 import net.sf.ehcache.config.CacheConfiguration.CacheEventListenerFactoryConfiguration;
043 import net.sf.ehcache.config.Configuration;
044 import net.sf.ehcache.config.ConfigurationFactory;
045 import net.sf.ehcache.config.FactoryConfiguration;
046 import net.sf.ehcache.event.NotificationScope;
047
048
051 public class EhcacheConfigurationHelperUtil {
052
053 public static ObjectValuePair<
054 Configuration, PortalCacheManagerConfiguration>
055 getConfiguration(String configurationPath) {
056
057 return getConfiguration(configurationPath, false, false);
058 }
059
060 public static ObjectValuePair<
061 Configuration, PortalCacheManagerConfiguration>
062 getConfiguration(String configurationPath, boolean clusterAware) {
063
064 return getConfiguration(configurationPath, clusterAware, false);
065 }
066
067 public static ObjectValuePair<
068 Configuration, PortalCacheManagerConfiguration>
069 getConfiguration(
070 String configurationPath, boolean clusterAware,
071 boolean usingDefault) {
072
073 if (configurationPath == null) {
074 throw new NullPointerException("Configuration path is null");
075 }
076
077 return getConfiguration(
078 EhcacheConfigurationHelperUtil.class.getResource(configurationPath),
079 clusterAware, usingDefault);
080 }
081
082 public static ObjectValuePair<
083 Configuration, PortalCacheManagerConfiguration>
084 getConfiguration(URL configurationURL) {
085
086 return getConfiguration(configurationURL, false, false);
087 }
088
089 public static ObjectValuePair<
090 Configuration, PortalCacheManagerConfiguration>
091 getConfiguration(URL configurationURL, boolean clusterAware) {
092
093 return getConfiguration(configurationURL, clusterAware, false);
094 }
095
096 public static ObjectValuePair<
097 Configuration, PortalCacheManagerConfiguration>
098 getConfiguration(
099 URL configurationURL, boolean clusterAware, boolean usingDefault) {
100
101 if (configurationURL == null) {
102 throw new NullPointerException("Configuration path is null");
103 }
104
105 Configuration ehcacheConfiguration =
106 ConfigurationFactory.parseConfiguration(configurationURL);
107
108 List<?> peerProviderConfiguration =
109 ehcacheConfiguration.
110 getCacheManagerPeerProviderFactoryConfiguration();
111
112 if (!peerProviderConfiguration.isEmpty() &&
113 (!clusterAware || !PropsValues.CLUSTER_LINK_ENABLED ||
114 PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED)) {
115
116 peerProviderConfiguration.clear();
117 }
118
119 peerProviderConfiguration =
120 ehcacheConfiguration.
121 getCacheManagerPeerListenerFactoryConfigurations();
122
123 if (!peerProviderConfiguration.isEmpty() &&
124 (!clusterAware || !PropsValues.CLUSTER_LINK_ENABLED ||
125 PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED)) {
126
127 peerProviderConfiguration.clear();
128 }
129
130 Set<CallbackConfiguration> cacheManagerListenerConfigurations =
131 _getCacheManagerListenerConfigurations(ehcacheConfiguration);
132
133 PortalCacheConfiguration defaultPortalCacheConfiguration =
134 _parseCacheConfiguration(
135 ehcacheConfiguration.getDefaultCacheConfiguration(),
136 clusterAware, usingDefault);
137
138 Set<PortalCacheConfiguration> portalCacheConfigurations =
139 new HashSet<PortalCacheConfiguration>();
140
141 Map<String, CacheConfiguration> cacheConfigurations =
142 ehcacheConfiguration.getCacheConfigurations();
143
144 for (Map.Entry<String, CacheConfiguration> entry :
145 cacheConfigurations.entrySet()) {
146
147 portalCacheConfigurations.add(
148 _parseCacheConfiguration(
149 entry.getValue(), clusterAware, usingDefault));
150 }
151
152 PortalCacheManagerConfiguration portalCacheManagerConfiguration =
153 new PortalCacheManagerConfiguration(
154 cacheManagerListenerConfigurations,
155 defaultPortalCacheConfiguration, portalCacheConfigurations);
156
157 return new ObjectValuePair<
158 Configuration, PortalCacheManagerConfiguration>(
159 ehcacheConfiguration, portalCacheManagerConfiguration);
160 }
161
162 private static CacheListenerScope _getCacheListenerScope(
163 NotificationScope notificationScope) {
164
165 if (notificationScope == NotificationScope.ALL) {
166 return CacheListenerScope.ALL;
167 }
168 else if (notificationScope == NotificationScope.LOCAL) {
169 return CacheListenerScope.LOCAL;
170 }
171 else if (notificationScope == NotificationScope.REMOTE) {
172 return CacheListenerScope.REMOTE;
173 }
174
175 throw new IllegalArgumentException(
176 "Unable to parse notification scope " + notificationScope);
177 }
178
179 private static Set<CallbackConfiguration>
180 _getCacheManagerListenerConfigurations(
181 Configuration ehcacheConfiguration) {
182
183 FactoryConfiguration<?> factoryConfiguration =
184 ehcacheConfiguration.
185 getCacheManagerEventListenerFactoryConfiguration();
186
187 if (factoryConfiguration == null) {
188 return Collections.emptySet();
189 }
190
191 Properties properties = _parseProperties(
192 factoryConfiguration.getProperties(),
193 factoryConfiguration.getPropertySeparator());
194
195 properties.put(
196 EhcacheConstants.CACHE_MANAGER_LISTENER_FACTORY_CLASS_NAME,
197 factoryConfiguration.getFullyQualifiedClassPath());
198 properties.put(
199 EhcacheConstants.PORTAL_CACHE_MANAGER_NAME,
200 ehcacheConfiguration.getName());
201
202 return Collections.singleton(
203 new CallbackConfiguration(
204 EhcacheCallbackFactory.INSTANCE, properties));
205 }
206
207 private static PortalCacheConfiguration _parseCacheConfiguration(
208 CacheConfiguration cacheConfiguration, boolean clusterAware,
209 boolean usingDefault) {
210
211 if (cacheConfiguration == null) {
212 return null;
213 }
214
215 String portalCacheName = cacheConfiguration.getName();
216
217 if (portalCacheName == null) {
218 portalCacheName =
219 PortalCacheConfiguration.DEFAULT_PORTAL_CACHE_NAME;
220 }
221
222 Map<CallbackConfiguration, CacheListenerScope>
223 cacheListenerConfigurations =
224 new HashMap<CallbackConfiguration, CacheListenerScope>();
225
226 List<CacheEventListenerFactoryConfiguration>
227 cacheEventListenerConfigurations =
228 cacheConfiguration.getCacheEventListenerConfigurations();
229
230 for (CacheEventListenerFactoryConfiguration
231 cacheEventListenerFactoryConfiguration :
232 cacheEventListenerConfigurations) {
233
234 String fullyQualifiedClassPath =
235 cacheEventListenerFactoryConfiguration.
236 getFullyQualifiedClassPath();
237
238 Properties properties = _parseProperties(
239 cacheEventListenerFactoryConfiguration.getProperties(),
240 cacheEventListenerFactoryConfiguration. getPropertySeparator());
241
242 CacheListenerScope cacheListenerScope = _getCacheListenerScope(
243 cacheEventListenerFactoryConfiguration.getListenFor());
244
245 if (fullyQualifiedClassPath.contains(
246 "LiferayCacheEventListenerFactory") ||
247 fullyQualifiedClassPath.contains(
248 "net.sf.ehcache.distribution")) {
249
250 if (clusterAware && PropsValues.CLUSTER_LINK_ENABLED) {
251 if (PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED) {
252 cacheListenerConfigurations.put(
253 new CallbackConfiguration(
254 ClusterLinkCallbackFactory.INSTANCE,
255 properties),
256 cacheListenerScope);
257 }
258 else {
259 properties.put(
260 EhcacheConstants.
261 CACHE_EVENT_LISTENER_FACTORY_CLASS_NAME,
262 cacheEventListenerFactoryConfiguration.
263 getFullyQualifiedClassPath());
264
265 cacheListenerConfigurations.put(
266 new CallbackConfiguration(
267 EhcacheCallbackFactory.INSTANCE, properties),
268 cacheListenerScope);
269 }
270 }
271 }
272 else if (!usingDefault) {
273 properties.put(
274 EhcacheConstants.CACHE_EVENT_LISTENER_FACTORY_CLASS_NAME,
275 cacheEventListenerFactoryConfiguration.
276 getFullyQualifiedClassPath());
277
278 cacheListenerConfigurations.put(
279 new CallbackConfiguration(
280 EhcacheCallbackFactory.INSTANCE, properties),
281 cacheListenerScope);
282 }
283 }
284
285 cacheEventListenerConfigurations.clear();
286
287 CallbackConfiguration bootstrapLoaderConfiguration = null;
288
289 BootstrapCacheLoaderFactoryConfiguration
290 bootstrapCacheLoaderFactoryConfiguration =
291 cacheConfiguration.
292 getBootstrapCacheLoaderFactoryConfiguration();
293
294 if (bootstrapCacheLoaderFactoryConfiguration != null) {
295 Properties properties = _parseProperties(
296 bootstrapCacheLoaderFactoryConfiguration.getProperties(),
297 bootstrapCacheLoaderFactoryConfiguration.
298 getPropertySeparator());
299
300 if (clusterAware && PropsValues.CLUSTER_LINK_ENABLED) {
301 if (PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED) {
302 bootstrapLoaderConfiguration = new CallbackConfiguration(
303 ClusterLinkCallbackFactory.INSTANCE, properties);
304 }
305 else {
306 properties.put(
307 EhcacheConstants.
308 BOOTSTRAP_CACHE_LOADER_FACTORY_CLASS_NAME,
309 bootstrapCacheLoaderFactoryConfiguration.
310 getFullyQualifiedClassPath());
311
312 bootstrapLoaderConfiguration = new CallbackConfiguration(
313 EhcacheCallbackFactory.INSTANCE, properties);
314 }
315 }
316
317 cacheConfiguration.addBootstrapCacheLoaderFactory(null);
318 }
319
320 return new PortalCacheConfiguration(
321 portalCacheName, cacheListenerConfigurations,
322 bootstrapLoaderConfiguration);
323 }
324
325 private static Properties _parseProperties(
326 String propertiesString, String propertySeparator) {
327
328 Properties properties = new Properties();
329
330 if (propertiesString == null) {
331 return properties;
332 }
333
334 if (propertySeparator == null) {
335 propertySeparator = StringPool.COMMA;
336 }
337
338 String propertyLines = propertiesString.trim();
339
340 propertyLines = StringUtil.replace(
341 propertyLines, propertySeparator, StringPool.NEW_LINE);
342
343 try {
344 properties.load(new UnsyncStringReader(propertyLines));
345 }
346 catch (IOException ioe) {
347 throw new RuntimeException(ioe);
348 }
349
350 return properties;
351 }
352
353 }