diff --git a/config/alfresco/cache-context.xml b/config/alfresco/cache-context.xml index daaeb748c2..f40fda1024 100644 --- a/config/alfresco/cache-context.xml +++ b/config/alfresco/cache-context.xml @@ -15,10 +15,16 @@ - classpath:ehcache-transactional.xml + classpath:alfresco/ehcache-transactional.xml + + + + + + @@ -28,8 +34,10 @@ + + + - nullPermissionCache @@ -51,7 +59,6 @@ - nullPermissionTransactionalCache @@ -69,8 +76,10 @@ + + + - userToAuthorityCache @@ -92,7 +101,6 @@ - userToAuthorityTransactionalCache @@ -110,8 +118,10 @@ + + + - permissionsAccessCache @@ -151,8 +161,10 @@ + + + - nodeOwnerCache @@ -174,7 +186,6 @@ - nodeOwnerTransactionalCache diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index ca532b33d6..4abd930294 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -823,11 +823,4 @@ - - - - classpath:ehcache.xml - - - diff --git a/config/alfresco/domain/hibernate-cfg.properties b/config/alfresco/domain/hibernate-cfg.properties index a8bf81174c..fffc43b392 100644 --- a/config/alfresco/domain/hibernate-cfg.properties +++ b/config/alfresco/domain/hibernate-cfg.properties @@ -7,7 +7,7 @@ hibernate.show_sql=false hibernate.hbm2ddl.auto=update hibernate.cache.use_query_cache=true hibernate.max_fetch_depth=10 -hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider +hibernate.cache.provider_class=org.alfresco.repo.cache.InternalEhCacheManagerFactoryBean hibernate.cache.use_second_level_cache=true hibernate.default_batch_fetch_size=1 hibernate.jdbc.batch_size=32 diff --git a/config/ehcache.xml b/config/alfresco/ehcache-default.xml similarity index 100% rename from config/ehcache.xml rename to config/alfresco/ehcache-default.xml diff --git a/config/ehcache-transactional.xml b/config/alfresco/ehcache-transactional.xml similarity index 100% rename from config/ehcache-transactional.xml rename to config/alfresco/ehcache-transactional.xml diff --git a/source/java/org/alfresco/repo/cache/EhCacheTracerJob.java b/source/java/org/alfresco/repo/cache/EhCacheTracerJob.java index 165f293328..6f6840865b 100644 --- a/source/java/org/alfresco/repo/cache/EhCacheTracerJob.java +++ b/source/java/org/alfresco/repo/cache/EhCacheTracerJob.java @@ -26,8 +26,8 @@ import net.sf.ehcache.Cache; import net.sf.ehcache.CacheException; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; +import net.sf.ehcache.Status; -import org.alfresco.error.AlfrescoRuntimeException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.Job; @@ -115,7 +115,7 @@ public class EhCacheTracerJob implements Job public CacheAnalysis(Cache cache) throws CacheException { this.cache = cache; - if (this.cache.getStatus() == Cache.STATUS_ALIVE) + if (this.cache.getStatus().equals(Status.STATUS_ALIVE)) { try { @@ -166,21 +166,6 @@ public class EhCacheTracerJob implements Job } } - public String getStatusStr() - { - switch (cache.getStatus()) - { - case Cache.STATUS_ALIVE: - return "ALIVE"; - case Cache.STATUS_DISPOSED: - return "DISPOSED"; - case Cache.STATUS_UNINITIALISED: - return "UNINITIALIZED"; - default: - throw new AlfrescoRuntimeException("Unknown cache status: " + cache.getStatus()); - } - } - public String toString() { double sizeMB = (double)getSize()/1024.0/1024.0; diff --git a/source/java/org/alfresco/repo/cache/InternalEhCacheManagerFactoryBean.java b/source/java/org/alfresco/repo/cache/InternalEhCacheManagerFactoryBean.java new file mode 100644 index 0000000000..3830803457 --- /dev/null +++ b/source/java/org/alfresco/repo/cache/InternalEhCacheManagerFactoryBean.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ +package org.alfresco.repo.cache; + +import java.io.FileNotFoundException; +import java.net.URL; +import java.util.Properties; + +import net.sf.ehcache.CacheManager; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.cache.Cache; +import org.hibernate.cache.CacheException; +import org.hibernate.cache.CacheProvider; +import org.hibernate.cache.EhCacheProvider; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.util.ResourceUtils; + +/** + * Alfresco-specific cache manager factory. + *

+ * The purpose of this bean is to provide a common point from which the system-wide + * EHCache CacheManager singleton is created. Hibernate and Spring + * will all pick up the same CacheManager instance. It then becomes + * possible to initialise this instance in whichever way we require, provided it + * is done in a well-known (non-configurable) way. + *

+ * For Alfresco purposes, there are two files that are looked for: + *

    + *
  • classpath:alfresco/extension/ehcache-custom.xml, which will take precedence
  • + *
  • classpath:alfresco/ehcache.xml, which is the default shipped with Alfresco
  • + *
+ *

+ * The EHCache static singleton instance is used but ensuring that all access to the + * instance goes through the required initialization code first. + *

+ * TODO: Provide mixing of config so that cache definitions in the custom file override + * those in the default file + * + * @see #getInstance() + * + * @author Derek Hulley + */ +public class InternalEhCacheManagerFactoryBean implements FactoryBean, CacheProvider +{ + public static final String CUSTOM_CONFIGURATION_FILE = "classpath:alfresco/extension/ehcache-custom.xml"; + public static final String DEFAULT_CONFIGURATION_FILE = "classpath:alfresco/ehcache-default.xml"; + + private static Log logger = LogFactory.getLog(InternalEhCacheManagerFactoryBean.class); + + /** keep track of the singleton status to avoid work */ + private static boolean initialized; + /** used to ensure that the existing Hibernate logic is maintained */ + private static EhCacheProvider hibernateEhCacheProvider = new EhCacheProvider(); + + /** + * Default constructor required by Hibernate. In fact, we anticipate several + * instances of this class to be created. + */ + public InternalEhCacheManagerFactoryBean() + { + } + + /** + * News up the singleton cache manager according to the rules set out + * in the class comments. + */ + private static synchronized void initCacheManager() + { + if (initialized) + { + return; + } + try + { + boolean defaultLocation = false; + try + { + URL configUrl = ResourceUtils.getURL(CUSTOM_CONFIGURATION_FILE); + CacheManager.create(configUrl); + } + catch (FileNotFoundException e) + { + // try the alfresco default + URL configUrl = ResourceUtils.getURL(DEFAULT_CONFIGURATION_FILE); + CacheManager.create(configUrl); // this file MUST be present + defaultLocation = true; + } + // done + if (logger.isDebugEnabled()) + { + logger.debug("Created EHCache CacheManager instance: \n" + + " configuration: " + (defaultLocation ? DEFAULT_CONFIGURATION_FILE : CUSTOM_CONFIGURATION_FILE)); + } + initialized = true; + } + catch (Throwable e) + { + throw new AlfrescoRuntimeException("EHCache configuration failed", e); + } + } + + /** + * @return Returns the properly initialized instance for Alfresco internal use + * + * @see #initCacheManager() + */ + public static CacheManager getInstance() + { + initCacheManager(); + return CacheManager.getInstance(); + } + + /** + * @see #hibernateEhCacheProvider + */ + public Cache buildCache(String regionName, Properties properties) throws CacheException + { + initCacheManager(); + return hibernateEhCacheProvider.buildCache(regionName, properties); + } + + /** + * @see #hibernateEhCacheProvider + */ + public boolean isMinimalPutsEnabledByDefault() + { + return hibernateEhCacheProvider.isMinimalPutsEnabledByDefault(); + } + + /** + * @see #hibernateEhCacheProvider + */ + public long nextTimestamp() + { + return hibernateEhCacheProvider.nextTimestamp(); + } + + /** + * @see #initCacheManager() + * @see #hibernateEhCacheProvider + */ + public void start(Properties properties) throws CacheException + { + initCacheManager(); + hibernateEhCacheProvider.start(properties); + } + + /** + * @see #initCacheManager() + * @see #hibernateEhCacheProvider + */ + public void stop() + { + initCacheManager(); + hibernateEhCacheProvider.stop(); + } + + /** + * @return Returns the singleton cache manager + * + * @see #initCacheManager() + */ + public Object getObject() throws Exception + { + initCacheManager(); + return CacheManager.getInstance(); + } + + /** + * @return Returns the singleton cache manager type + */ + public Class getObjectType() + { + return CacheManager.class; + } + + /** + * @return Returns true always + */ + public boolean isSingleton() + { + return true; + } +}