diff --git a/config/alfresco/public-rest-context.xml b/config/alfresco/public-rest-context.xml
index fe564240b3..f31a6617ac 100644
--- a/config/alfresco/public-rest-context.xml
+++ b/config/alfresco/public-rest-context.xml
@@ -1,981 +1,985 @@
-
-
-
-
- true
- alfresco/templates/publicapi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- webscript.default
-
-
-
-
-
-
-
-
-
- Public Api
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- alfresco.messages.rest-framework-messages
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.documentlibrary.files-added
- org.alfresco.documentlibrary.files-updated
- org.alfresco.documentlibrary.files-deleted
- org.alfresco.documentlibrary.file-added
- org.alfresco.documentlibrary.file-created
- org.alfresco.documentlibrary.file-deleted
- org.alfresco.documentlibrary.file-liked
- org.alfresco.documentlibrary.inline-edit
- org.alfresco.documentlibrary.folder-liked
- org.alfresco.documentlibrary.folder-added
- org.alfresco.documentlibrary.folder-deleted
- org.alfresco.documentlibrary.folders-added
- org.alfresco.documentlibrary.folders-deleted
-
-
-
-
-
-
-
-
- org.alfresco.site.user-joined
- org.alfresco.site.user-left
- org.alfresco.site.user-role-changed
- org.alfresco.site.group-added
- org.alfresco.site.group-removed
- org.alfresco.site.group-role-changed
-
-
-
-
-
-
-
-
- org.alfresco.discussions.reply-created
-
-
-
-
-
-
-
-
- org.alfresco.subscriptions.followed
- org.alfresco.subscriptions.subscribed
-
-
-
-
-
-
-
-
- org.alfresco.wiki.page-created
- org.alfresco.wiki.page-edited
- org.alfresco.wiki.page-renamed
- org.alfresco.wiki.page-deleted
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Activities
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {http://www.alfresco.org/model/content/1.0}folder
- {http://www.alfresco.org/model/content/1.0}content
- {http://www.alfresco.org/model/cmis/custom}*
-
-
-
-
- {http://www.alfresco.org/model/forum/1.0}forums
- {http://www.alfresco.org/model/forum/1.0}forum
- {http://www.alfresco.org/model/forum/1.0}topic
- {http://www.alfresco.org/model/forum/1.0}post
- {http://www.alfresco.org/model/content/1.0}category
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.NodeRatings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Nodes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Favourites
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.SiteMembershipRequests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.People
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Preferences
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Sites
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {http://www.alfresco.org/model/content/1.0}folder
- {http://www.alfresco.org/model/content/1.0}content
- {http://www.alfresco.org/model/cmis/custom}*
-
-
-
-
- {http://www.alfresco.org/model/forum/1.0}forums
- {http://www.alfresco.org/model/forum/1.0}forum
- {http://www.alfresco.org/model/forum/1.0}topic
- {http://www.alfresco.org/model/forum/1.0}post
- {http://www.alfresco.org/model/content/1.0}category
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Tags
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.api.Networks
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.workflow.api.Deployments
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.workflow.api.ProcessDefinitions
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.workflow.api.Processes
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.workflow.api.Tasks
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.alfresco.rest.workflow.api.Activities
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ true
+ alfresco/templates/publicapi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ webscript.default
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Public Api
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ alfresco.messages.rest-framework-messages
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.documentlibrary.files-added
+ org.alfresco.documentlibrary.files-updated
+ org.alfresco.documentlibrary.files-deleted
+ org.alfresco.documentlibrary.file-added
+ org.alfresco.documentlibrary.file-created
+ org.alfresco.documentlibrary.file-deleted
+ org.alfresco.documentlibrary.file-liked
+ org.alfresco.documentlibrary.inline-edit
+ org.alfresco.documentlibrary.folder-liked
+ org.alfresco.documentlibrary.folder-added
+ org.alfresco.documentlibrary.folder-deleted
+ org.alfresco.documentlibrary.folders-added
+ org.alfresco.documentlibrary.folders-deleted
+
+
+
+
+
+
+
+
+ org.alfresco.site.user-joined
+ org.alfresco.site.user-left
+ org.alfresco.site.user-role-changed
+ org.alfresco.site.group-added
+ org.alfresco.site.group-removed
+ org.alfresco.site.group-role-changed
+
+
+
+
+
+
+
+
+ org.alfresco.discussions.reply-created
+
+
+
+
+
+
+
+
+ org.alfresco.subscriptions.followed
+ org.alfresco.subscriptions.subscribed
+
+
+
+
+
+
+
+
+ org.alfresco.wiki.page-created
+ org.alfresco.wiki.page-edited
+ org.alfresco.wiki.page-renamed
+ org.alfresco.wiki.page-deleted
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Activities
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {http://www.alfresco.org/model/content/1.0}folder
+ {http://www.alfresco.org/model/content/1.0}content
+ {http://www.alfresco.org/model/cmis/custom}*
+
+
+
+
+ {http://www.alfresco.org/model/forum/1.0}forums
+ {http://www.alfresco.org/model/forum/1.0}forum
+ {http://www.alfresco.org/model/forum/1.0}topic
+ {http://www.alfresco.org/model/forum/1.0}post
+ {http://www.alfresco.org/model/content/1.0}category
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.NodeRatings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Nodes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Favourites
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.SiteMembershipRequests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.People
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Preferences
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Sites
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {http://www.alfresco.org/model/content/1.0}folder
+ {http://www.alfresco.org/model/content/1.0}content
+ {http://www.alfresco.org/model/cmis/custom}*
+
+
+
+
+ {http://www.alfresco.org/model/forum/1.0}forums
+ {http://www.alfresco.org/model/forum/1.0}forum
+ {http://www.alfresco.org/model/forum/1.0}topic
+ {http://www.alfresco.org/model/forum/1.0}post
+ {http://www.alfresco.org/model/content/1.0}category
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Tags
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.api.Networks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.workflow.api.Deployments
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.workflow.api.ProcessDefinitions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.workflow.api.Processes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.workflow.api.Tasks
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.alfresco.rest.workflow.api.Activities
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index bc2a8cedf3..9782b2e38a 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -206,11 +206,7 @@
-
-
-
-
-
+
@@ -222,7 +218,6 @@
-
@@ -235,6 +230,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/repo/web/scripts/RegistryAsynchronouslyRefreshedCache.java b/source/java/org/alfresco/repo/web/scripts/RegistryAsynchronouslyRefreshedCache.java
new file mode 100644
index 0000000000..83efba01b2
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/RegistryAsynchronouslyRefreshedCache.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2005-2013 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.repo.web.scripts;
+
+import org.alfresco.repo.cache.AbstractAsynchronouslyRefreshedCache;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
+import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
+import org.alfresco.util.PropertyCheck;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.extensions.webscripts.Registry;
+
+/**
+ * Asynchronously refreshed cache for repository webscripts.
+ *
+ * This does not stop gratuitous calls to refresh but will ensure that, once an instance has been created,
+ * a version of the registry is returned even if it is slighly out of date. This can be changed so that it waits
+ * for reset but is probably not required.
+ *
+ * @author Derek Hulley
+ * @since 4.2.0
+ */
+public class RegistryAsynchronouslyRefreshedCache extends AbstractAsynchronouslyRefreshedCache implements InitializingBean
+{
+ private static Log logger = LogFactory.getLog(RegistryAsynchronouslyRefreshedCache.class);
+
+ private ObjectFactory registryFactory;
+ private RetryingTransactionHelper retryingTransactionHelper;
+
+ /**
+ * @param registryFactory factory for web script registries
+ */
+ public void setRegistryFactory(ObjectFactory registryFactory)
+ {
+ this.registryFactory = registryFactory;
+ }
+
+ /**
+ * @param retryingTransactionHelper the retryingTransactionHelper to set
+ */
+ public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
+ {
+ this.retryingTransactionHelper = retryingTransactionHelper;
+ }
+
+ @Override
+ protected Registry buildCache(final String tenantId)
+ {
+ return retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback()
+ {
+ @Override
+ public Registry execute() throws Throwable
+ {
+ return doBuildCache(tenantId);
+ }
+ }, true, false);
+ }
+
+ /**
+ * This method is thread safe as per contract of {@link #buildCache(String)}.
+ */
+ private Registry doBuildCache(String tenantId)
+ {
+ Registry registry = registryFactory.getObject();
+ registry.reset();
+ logger.info("Fetching web script registry for tenant " + tenantId);
+ return registry;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception
+ {
+ PropertyCheck.mandatory(this, "registryFactory", registryFactory);
+ PropertyCheck.mandatory(this, "retryingTransactionHelper", retryingTransactionHelper);
+ super.afterPropertiesSet();
+ }
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java b/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java
index afe2634820..1cfd31a5b1 100644
--- a/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java
+++ b/source/java/org/alfresco/repo/web/scripts/TenantRepositoryContainer.java
@@ -1,159 +1,123 @@
-/*
- * Copyright (C) 2005-2013 Alfresco Software Limited.
- *
- * This file is part of Alfresco
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see .
- */
-package org.alfresco.repo.web.scripts;
-
-import org.alfresco.repo.cache.SimpleCache;
-import org.alfresco.repo.tenant.TenantAdminService;
-import org.alfresco.repo.tenant.TenantDeployer;
-import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
-import org.alfresco.service.transaction.TransactionService;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.ObjectFactory;
-import org.springframework.extensions.webscripts.Registry;
-
-
-/**
- * Tenant-aware Repository (server-tier) container for Web Scripts
- *
- * @author davidc
- */
-public class TenantRepositoryContainer extends RepositoryContainer implements TenantDeployer
-{
- // Logger
- protected static final Log logger = LogFactory.getLog(TenantRepositoryContainer.class);
-
- /** Component Dependencies */
- protected TenantAdminService tenantAdminService;
- protected TransactionService transactionService;
- protected ObjectFactory registryFactory;
- protected SimpleCache webScriptsRegistryCache;
- protected boolean initialized;
-
- /**
- * @param webScriptsRegistryCache
- */
- public void setWebScriptsRegistryCache(SimpleCache webScriptsRegistryCache)
- {
- this.webScriptsRegistryCache = webScriptsRegistryCache;
- }
-
- /**
- * @param registryFactory
- */
- public void setRegistryFactory(ObjectFactory registryFactory)
- {
- this.registryFactory = registryFactory;
- }
-
- /**
- * @param tenantAdminService
- */
- public void setTenantAdminService(TenantAdminService tenantAdminService)
- {
- this.tenantAdminService = tenantAdminService;
- }
-
- /**
- * @param transactionService the transactionService to set
- */
- public void setTransactionService(TransactionService transactionService)
- {
- super.setTransactionService(transactionService);
- this.transactionService = transactionService;
- }
-
-
- /* (non-Javadoc)
- * @see org.alfresco.web.scripts.AbstractRuntimeContainer#getRegistry()
- */
- @Override
- public Registry getRegistry()
- {
- String tenantDomain = tenantAdminService.getCurrentUserDomain();
- Registry registry = webScriptsRegistryCache.get(tenantDomain);
- if (registry == null)
- {
- registry = (Registry)registryFactory.getObject();
- // We only need to reset the registry if the superclass thinks its already initialized
- if (initialized)
- {
- registry.reset();
- }
- webScriptsRegistryCache.put(tenantDomain, registry);
- }
- return registry;
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#onEnableTenant()
- */
- public void onEnableTenant()
- {
- init();
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#onDisableTenant()
- */
- public void onDisableTenant()
- {
- destroy();
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#init()
- */
- public void init()
- {
- tenantAdminService.register(this);
-
- super.reset();
-
- initialized = true;
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.repo.tenant.TenantDeployer#destroy()
- */
- public void destroy()
- {
- webScriptsRegistryCache.remove(tenantAdminService.getCurrentUserDomain());
-
- initialized = false;
- }
-
- /* (non-Javadoc)
- * @see org.alfresco.web.scripts.AbstractRuntimeContainer#reset()
- */
- @Override
- public void reset()
- {
- transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback