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 String portalCacheName = cacheConfiguration.getName();
212
213 if (portalCacheName == null) {
214 portalCacheName =
215 PortalCacheConfiguration.DEFAULT_PORTAL_CACHE_NAME;
216 }
217
218 Map<CallbackConfiguration, CacheListenerScope>
219 cacheListenerConfigurations =
220 new HashMap<CallbackConfiguration, CacheListenerScope>();
221
222 List<CacheEventListenerFactoryConfiguration>
223 cacheEventListenerConfigurations =
224 cacheConfiguration.getCacheEventListenerConfigurations();
225
226 for (CacheEventListenerFactoryConfiguration
227 cacheEventListenerFactoryConfiguration :
228 cacheEventListenerConfigurations) {
229
230 String fullyQualifiedClassPath =
231 cacheEventListenerFactoryConfiguration.
232 getFullyQualifiedClassPath();
233
234 Properties properties = _parseProperties(
235 cacheEventListenerFactoryConfiguration.getProperties(),
236 cacheEventListenerFactoryConfiguration. getPropertySeparator());
237
238 CacheListenerScope cacheListenerScope = _getCacheListenerScope(
239 cacheEventListenerFactoryConfiguration.getListenFor());
240
241 if (fullyQualifiedClassPath.contains(
242 "LiferayCacheEventListenerFactory") ||
243 fullyQualifiedClassPath.contains(
244 "net.sf.ehcache.distribution")) {
245
246 if (clusterAware && PropsValues.CLUSTER_LINK_ENABLED) {
247 if (PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED) {
248 cacheListenerConfigurations.put(
249 new CallbackConfiguration(
250 ClusterLinkCallbackFactory.INSTANCE,
251 properties),
252 cacheListenerScope);
253 }
254 else {
255 properties.put(
256 EhcacheConstants.
257 CACHE_EVENT_LISTENER_FACTORY_CLASS_NAME,
258 cacheEventListenerFactoryConfiguration.
259 getFullyQualifiedClassPath());
260
261 cacheListenerConfigurations.put(
262 new CallbackConfiguration(
263 EhcacheCallbackFactory.INSTANCE, properties),
264 cacheListenerScope);
265 }
266 }
267 }
268 else if (!usingDefault) {
269 properties.put(
270 EhcacheConstants.CACHE_EVENT_LISTENER_FACTORY_CLASS_NAME,
271 cacheEventListenerFactoryConfiguration.
272 getFullyQualifiedClassPath());
273
274 cacheListenerConfigurations.put(
275 new CallbackConfiguration(
276 EhcacheCallbackFactory.INSTANCE, properties),
277 cacheListenerScope);
278 }
279 }
280
281 cacheEventListenerConfigurations.clear();
282
283 CallbackConfiguration bootstrapLoaderConfiguration = null;
284
285 BootstrapCacheLoaderFactoryConfiguration
286 bootstrapCacheLoaderFactoryConfiguration =
287 cacheConfiguration.
288 getBootstrapCacheLoaderFactoryConfiguration();
289
290 if (bootstrapCacheLoaderFactoryConfiguration != null) {
291 Properties properties = _parseProperties(
292 bootstrapCacheLoaderFactoryConfiguration.getProperties(),
293 bootstrapCacheLoaderFactoryConfiguration.
294 getPropertySeparator());
295
296 if (clusterAware && PropsValues.CLUSTER_LINK_ENABLED) {
297 if (PropsValues.EHCACHE_CLUSTER_LINK_REPLICATION_ENABLED) {
298 bootstrapLoaderConfiguration = new CallbackConfiguration(
299 ClusterLinkCallbackFactory.INSTANCE, properties);
300 }
301 else {
302 properties.put(
303 EhcacheConstants.
304 BOOTSTRAP_CACHE_LOADER_FACTORY_CLASS_NAME,
305 bootstrapCacheLoaderFactoryConfiguration.
306 getFullyQualifiedClassPath());
307
308 bootstrapLoaderConfiguration = new CallbackConfiguration(
309 EhcacheCallbackFactory.INSTANCE, properties);
310 }
311 }
312
313 cacheConfiguration.addBootstrapCacheLoaderFactory(null);
314 }
315
316 return new PortalCacheConfiguration(
317 portalCacheName, cacheListenerConfigurations,
318 bootstrapLoaderConfiguration);
319 }
320
321 private static Properties _parseProperties(
322 String propertiesString, String propertySeparator) {
323
324 Properties properties = new Properties();
325
326 if (propertiesString == null) {
327 return properties;
328 }
329
330 if (propertySeparator == null) {
331 propertySeparator = StringPool.COMMA;
332 }
333
334 String propertyLines = propertiesString.trim();
335
336 propertyLines = StringUtil.replace(
337 propertyLines, propertySeparator, StringPool.NEW_LINE);
338
339 try {
340 properties.load(new UnsyncStringReader(propertyLines));
341 }
342 catch (IOException ioe) {
343 throw new RuntimeException(ioe);
344 }
345
346 return properties;
347 }
348
349 }