From 200a8c3843f2e193e6a7326d7c134e85d3424e6a Mon Sep 17 00:00:00 2001 From: Jan Vonka Date: Wed, 22 Apr 2009 16:30:51 +0000 Subject: [PATCH] Dictionary Cache improvements - ensure CMIS Dictionary Registry is MT-aware git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14057 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/cmis-api-context.xml | 3 + .../CMISAbstractDictionaryService.java | 58 +++++++++++++++---- .../repo/dictionary/DictionaryBootstrap.java | 12 +++- .../repo/dictionary/DictionaryDAOImpl.java | 12 +++- .../repo/dictionary/DictionaryListener.java | 7 ++- .../DictionaryRepositoryBootstrap.java | 10 +++- 6 files changed, 82 insertions(+), 20 deletions(-) diff --git a/config/alfresco/cmis-api-context.xml b/config/alfresco/cmis-api-context.xml index a3e47e9b4d..ab97ee43e8 100644 --- a/config/alfresco/cmis-api-context.xml +++ b/config/alfresco/cmis-api-context.xml @@ -31,6 +31,9 @@ + + + diff --git a/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java b/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java index 09ffcb9ce1..578d8f31fc 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java @@ -31,6 +31,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; import org.alfresco.cmis.CMISDataTypeEnum; import org.alfresco.cmis.CMISDictionaryService; @@ -43,6 +44,7 @@ import org.alfresco.cmis.mapping.CMISMapping; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.repo.dictionary.DictionaryDAO; import org.alfresco.repo.dictionary.DictionaryListener; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.namespace.QName; import org.alfresco.util.AbstractLifecycleBean; @@ -65,6 +67,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea private DictionaryDAO dictionaryDAO; protected CMISMapping cmisMapping; protected DictionaryService dictionaryService; + protected TenantService tenantService; /** * Set the mapping service @@ -95,11 +98,21 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea { this.dictionaryDAO = dictionaryDAO; } + + /** + * Set the tenant Service + * + * @param tenantService + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } - // TODO: Handle tenants // TODO: read / write locks - private DictionaryRegistry registry; + /** CMIS Dictionary Registry (tenant-aware) */ + private Map registryMap = new ConcurrentHashMap(4); /** @@ -205,14 +218,26 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea return builder.toString(); } } - + + private DictionaryRegistry getRegistry() + { + String tenantDomain = tenantService.getCurrentUserDomain(); + DictionaryRegistry registry = registryMap.get(tenantDomain); + if (registry == null) + { + init(); + registry = registryMap.get(tenantDomain); + } + return registry; + } + /* * (non-Javadoc) * @see org.alfresco.cmis.dictionary.CMISDictionaryService#findType(org.alfresco.cmis.dictionary.CMISTypeId) */ public CMISTypeDefinition findType(CMISTypeId typeId) { - return registry.objectDefsByTypeId.get(typeId); + return getRegistry().objectDefsByTypeId.get(typeId); } /* @@ -246,11 +271,11 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea CMISTypeDefinition typeDef = null; if (scopeByRelationship) { - typeDef = registry.assocDefsByQName.get(clazz); + typeDef = getRegistry().assocDefsByQName.get(clazz); } else { - typeDef = registry.typeDefsByQName.get(clazz); + typeDef = getRegistry().typeDefsByQName.get(clazz); } // ensure matches one of provided matching scopes @@ -276,7 +301,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea */ public CMISTypeDefinition findTypeForTable(String tableName) { - CMISTypeDefinition typeDef = registry.typeDefsByTable.get(tableName.toLowerCase()); + CMISTypeDefinition typeDef = getRegistry().typeDefsByTable.get(tableName.toLowerCase()); return typeDef; } @@ -286,7 +311,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea */ public Collection getAllTypes() { - return Collections.unmodifiableCollection(registry.typeDefsByTypeId.values()); + return Collections.unmodifiableCollection(getRegistry().typeDefsByTypeId.values()); } /* @@ -295,7 +320,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea */ public CMISPropertyDefinition findProperty(QName property, CMISTypeDefinition matchingType) { - CMISPropertyDefinition propDef = registry.propDefsByQName.get(property); + CMISPropertyDefinition propDef = getRegistry().propDefsByQName.get(property); return getProperty(propDef, matchingType); } @@ -305,7 +330,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea */ public CMISPropertyDefinition findProperty(String property, CMISTypeDefinition matchingType) { - CMISPropertyDefinition propDef = registry.propDefsByName.get(property.toLowerCase()); + CMISPropertyDefinition propDef = getRegistry().propDefsByName.get(property.toLowerCase()); return getProperty(propDef, matchingType); } @@ -413,7 +438,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea } // publish new registry - this.registry = registry; + registryMap.put(tenantService.getCurrentUserDomain(), registry); if (logger.isInfoEnabled()) logger.info("Initialized CMIS Dictionary. Types:" + registry.typeDefsByTypeId.size() + ", Properties:" + registry.propDefsByPropId.size()); @@ -435,7 +460,16 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea { init(); } - + + /* + * (non-Javadoc) + * @see org.alfresco.repo.dictionary.DictionaryListener#afterDictionaryDestroy() + */ + public void afterDictionaryDestroy() + { + registryMap.remove(tenantService.getCurrentUserDomain()); + } + /* * (non-Javadoc) * @see org.alfresco.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent) diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryBootstrap.java b/source/java/org/alfresco/repo/dictionary/DictionaryBootstrap.java index 4c4b2d2705..3a192c34d5 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryBootstrap.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -150,7 +150,7 @@ public class DictionaryBootstrap implements DictionaryListener } } } - + /* * (non-Javadoc) * @see org.alfresco.repo.dictionary.DictionaryListener#afterInit() @@ -159,6 +159,14 @@ public class DictionaryBootstrap implements DictionaryListener { } + /* + * (non-Javadoc) + * @see org.alfresco.repo.dictionary.DictionaryListener#onDictionaryDestroy() + */ + public void afterDictionaryDestroy() + { + } + /** * Register the static resource bundles */ diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java index 3185ea7d64..54eea65b1b 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java @@ -147,7 +147,7 @@ public class DictionaryDAOImpl implements DictionaryDAO // initialise empty dictionary & namespaces putCompiledModels(tenantDomain, new HashMap()); putUriToModels(tenantDomain, new HashMap>()); - + namespaceDAO.init(); // populate the dictionary @@ -155,8 +155,8 @@ public class DictionaryDAOImpl implements DictionaryDAO { dictionaryListener.onDictionaryInit(); } - - // populate the dictionary + + // notify registered listeners that dictionary has been initialised for (DictionaryListener dictionaryListener : dictionaryListeners) { dictionaryListener.afterDictionaryInit(); @@ -177,6 +177,12 @@ public class DictionaryDAOImpl implements DictionaryDAO namespaceDAO.destroy(); + // notify registered listeners that dictionary has been destroyed + for (DictionaryListener dictionaryDeployer : dictionaryListeners) + { + dictionaryDeployer.afterDictionaryDestroy(); + } + logger.info("Dictionary destroyed"); } diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryListener.java b/source/java/org/alfresco/repo/dictionary/DictionaryListener.java index 0128c1f92b..4c44944225 100755 --- a/source/java/org/alfresco/repo/dictionary/DictionaryListener.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryListener.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -37,6 +37,9 @@ public interface DictionaryListener // callback for (re-)initialising the Dictionary caches public void onDictionaryInit(); - // callback once initialisation is complete + // callback once dictionary destroy is complete + public void afterDictionaryDestroy(); + + // callback once dictionary initialisation is complete public void afterDictionaryInit(); } diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java b/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java index 5a01f83066..50a72197b3 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -293,6 +293,14 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme { } + /* + * (non-Javadoc) + * @see org.alfresco.repo.dictionary.DictionaryListener#onDictionaryDestroy() + */ + public void afterDictionaryDestroy() + { + } + public void initMessages() { if (this.repositoryMessagesLocations != null)