diff --git a/config/alfresco/repo-admin-context.xml b/config/alfresco/repo-admin-context.xml
index 14b9e8d22d..caf0baf1ab 100755
--- a/config/alfresco/repo-admin-context.xml
+++ b/config/alfresco/repo-admin-context.xml
@@ -88,7 +88,8 @@
-
+
+
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java
index b70d9b74e1..330efea401 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java
@@ -172,4 +172,7 @@ public interface DictionaryDAO extends ModelQuery
* Destroy the Dictionary
*/
public void destroy();
+
+ // MT-specific
+ public boolean isModelInherited(QName name);
}
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
index f84ac8022a..76eb8e3e87 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
@@ -704,23 +704,54 @@ public class DictionaryDAOImpl implements DictionaryDAO
*/
public Collection getModels()
{
+ // get all models - including inherited models, if applicable
return getCompiledModels().keySet();
}
- // return all tenant-specific models and all shared (non-overridden) models
+ // MT-specific
+ public boolean isModelInherited(QName modelName)
+ {
+ String tenantDomain = tenantService.getCurrentUserDomain();
+ if (tenantDomain != "")
+ {
+ // get tenant-specific model (if any)
+ CompiledModel model = getCompiledModels(tenantDomain).get(modelName);
+ if (model != null)
+ {
+ return false;
+ }
+ // else drop down to check for shared (core/system) models ...
+ }
+
+ // get non-tenant model (if any)
+ CompiledModel model = getCompiledModels("").get(modelName);
+ if (model == null)
+ {
+ throw new DictionaryException("d_dictionary.model.err.no_model", modelName);
+ }
+
+ if (tenantDomain != "")
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
private Map getCompiledModels()
{
String tenantDomain = tenantService.getCurrentUserDomain();
if (tenantDomain != "")
{
- // return all tenant-specific models and all shared (non-overridden) models
+ // return all tenant-specific models and all inherited (non-overridden) models
Map filteredModels = new HashMap();
// get tenant models (if any)
Map tenantModels = getCompiledModels(tenantDomain);
- // get non-tenant models (if any)
- // note: these will be shared, if not overridden - could be core/system model or additional custom model shared between tenants
+ // get non-tenant models - these will include core/system models and any additional custom models (which are implicitly available to all tenants)
Map nontenantModels = getCompiledModels("");
// check for overrides
@@ -744,15 +775,10 @@ public class DictionaryDAOImpl implements DictionaryDAO
}
else
{
+ // return all (non-tenant) models
return getCompiledModels("");
}
}
-
- // used for clean-up, e.g. when deleting a tenant
- protected Collection getNonSharedModels()
- {
- return getCompiledModels(tenantService.getCurrentUserDomain()).keySet();
- }
/* (non-Javadoc)
* @see org.alfresco.repo.dictionary.impl.DictionaryDAO#getModel(org.alfresco.repo.ref.QName)
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java b/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java
index 0964f2a52c..82a15ad3ca 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryModelType.java
@@ -39,6 +39,8 @@ import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+import org.alfresco.repo.tenant.Tenant;
+import org.alfresco.repo.tenant.TenantDeployerService;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.TransactionListener;
@@ -49,6 +51,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.cmr.dictionary.NamespaceDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.NodeRef;
@@ -73,6 +76,7 @@ import org.apache.commons.logging.LogFactory;
public class DictionaryModelType implements ContentServicePolicies.OnContentUpdatePolicy,
NodeServicePolicies.OnUpdatePropertiesPolicy,
NodeServicePolicies.BeforeDeleteNodePolicy,
+ NodeServicePolicies.OnCreateNodePolicy,
NodeServicePolicies.OnRemoveAspectPolicy
{
// Logger
@@ -81,9 +85,12 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
/** Key to the pending models */
private static final String KEY_PENDING_MODELS = "dictionaryModelType.pendingModels";
- /** Key to the removed aspect */
+ /** Key to the removed "workingcopy" aspect */
private static final String KEY_WORKING_COPY = "dictionaryModelType.workingCopy";
+ /** Key to the removed "archived" aspect */
+ private static final String KEY_ARCHIVED = "dictionaryModelType.archived";
+
/** The dictionary DAO */
private DictionaryDAO dictionaryDAO;
@@ -111,6 +118,9 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
/** The tenant service */
private TenantService tenantService;
+ /** The tenant deployer service */
+ private TenantDeployerService tenantDeployerService;
+
/** Transaction listener */
private DictionaryModelTypeTransactionListener transactionListener;
@@ -207,6 +217,15 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
this.tenantService = tenantService;
}
+ /**
+ * Set the tenant admin service
+ *
+ * @param tenantAdminService the tenant admin service
+ */
+ public void setTenantDeployerService(TenantDeployerService tenantDeployerService)
+ {
+ this.tenantDeployerService = tenantDeployerService;
+ }
public void setStoreUrls(List storeUrls)
{
@@ -243,6 +262,12 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
this,
new JavaBehaviour(this, "onRemoveAspect"));
+ // Register interest in the onCreateNode policy for the dictionary model type
+ policyComponent.bindClassBehaviour(
+ QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
+ ContentModel.TYPE_DICTIONARY_MODEL,
+ new JavaBehaviour(this, "onCreateNode"));
+
// Create the transaction listener
this.transactionListener = new DictionaryModelTypeTransactionListener(this.nodeService, this.contentService);
}
@@ -303,26 +328,37 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
public void onRemoveAspect(NodeRef nodeRef, QName aspect)
{
- // undo/cancel checkout removes the aspect prior to deleting the node - hence need to track here
+ // undo/cancel checkout removes the "workingcopy" aspect prior to deleting the node - hence need to track here
if (aspect.equals(ContentModel.ASPECT_WORKING_COPY))
{
AlfrescoTransactionSupport.bindResource(KEY_WORKING_COPY, nodeRef);
}
+
+ // restore removes the "archived" aspect prior to restoring (via delete/move) the node - hence need to track here
+ if (aspect.equals(ContentModel.ASPECT_ARCHIVED))
+ {
+ AlfrescoTransactionSupport.bindResource(KEY_ARCHIVED, nodeRef);
+ }
}
- @SuppressWarnings("unchecked")
public void beforeDeleteNode(NodeRef nodeRef)
{
boolean workingCopy = nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY);
-
NodeRef wcNodeRef = (NodeRef)AlfrescoTransactionSupport.getResource(KEY_WORKING_COPY);
if ((wcNodeRef != null) && (wcNodeRef.equals(nodeRef)))
{
workingCopy = true;
}
+ boolean archived = nodeService.hasAspect(nodeRef, ContentModel.ASPECT_ARCHIVED);
+ NodeRef aNodeRef = (NodeRef)AlfrescoTransactionSupport.getResource(KEY_ARCHIVED);
+ if ((aNodeRef != null) && (aNodeRef.equals(nodeRef)))
+ {
+ archived = true;
+ }
+
// Ignore if the node is a working copy or archived
- if ((workingCopy == false) && (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_ARCHIVED) == false))
+ if (! (workingCopy || archived))
{
QName modelName = (QName)this.nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_NAME);
if (modelName != null)
@@ -336,6 +372,16 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
}
}
+ public void onCreateNode(ChildAssociationRef childAssocRef)
+ {
+ NodeRef nodeRef = childAssocRef.getChildRef();
+ Boolean value = (Boolean)nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_ACTIVE);
+ if ((value != null) && (value == true))
+ {
+ queueModel(nodeRef);
+ }
+ }
+
/**
* Dictionary model type transaction listener class.
*/
@@ -372,11 +418,13 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
if (pendingModels != null)
{
- for (final NodeRef nodeRef : pendingModels)
+ for (NodeRef pendingNodeRef : pendingModels)
{
- String tenantDomain = tenantService.getDomain(nodeRef.getStoreRef().getIdentifier());
+ String tenantDomain = tenantService.getDomain(pendingNodeRef.getStoreRef().getIdentifier());
String tenantAdminUserName = tenantService.getDomainUser(TenantService.ADMIN_BASENAME, tenantDomain);
+ final NodeRef nodeRef = tenantService.getBaseName(pendingNodeRef);
+
AuthenticationUtil.runAs(new RunAsWork