mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.2 to HEAD
19507: ALF-955: deletion of dynamic custom model 19553: Follow-on to r19507 (ALF-955) - fix testAutoRemovalOfVersionHistory git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19569 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -84,7 +84,7 @@
|
|||||||
<bean id="storeArchiveMap" class="org.alfresco.repo.node.StoreArchiveMap">
|
<bean id="storeArchiveMap" class="org.alfresco.repo.node.StoreArchiveMap">
|
||||||
<property name="archiveMap">
|
<property name="archiveMap">
|
||||||
<map>
|
<map>
|
||||||
<entry key="workspace://SpacesStore"><value>archive://SpacesStore</value></entry>
|
<entry key="workspace://SpacesStore"><value>${spaces.archive.store}</value></entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
<property name="tenantService">
|
<property name="tenantService">
|
||||||
@@ -228,11 +228,19 @@
|
|||||||
<ref bean="avmNodeService"/>
|
<ref bean="avmNodeService"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="nodeIndexer">
|
<property name="nodeIndexer">
|
||||||
<ref bean="nodeIndexer" />
|
<ref bean="nodeIndexer"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="cascadeInTransaction">
|
<property name="cascadeInTransaction">
|
||||||
<value>${system.cascadeDeleteInTransaction}</value>
|
<value>${system.cascadeDeleteInTransaction}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="tenantService">
|
||||||
|
<ref bean="tenantService"/>
|
||||||
|
</property>
|
||||||
|
<property name="storesToIgnorePolicies">
|
||||||
|
<list>
|
||||||
|
<value>${spaces.archive.store}</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="nodeAuditor" class="org.alfresco.repo.node.NodeAuditor">
|
<bean id="nodeAuditor" class="org.alfresco.repo.node.NodeAuditor">
|
||||||
|
@@ -27,18 +27,31 @@ package org.alfresco.repo.admin;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
import org.alfresco.service.cmr.admin.RepoAdminService;
|
import org.alfresco.service.cmr.admin.RepoAdminService;
|
||||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
@@ -61,6 +74,11 @@ public class RepoAdminServiceImplTest extends TestCase
|
|||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
|
|
||||||
|
private NodeService nodeService;
|
||||||
|
private ContentService contentService;
|
||||||
|
private SearchService searchService;
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
|
||||||
final String modelPrefix = "model-";
|
final String modelPrefix = "model-";
|
||||||
final static String MKR = "{MKR}";
|
final static String MKR = "{MKR}";
|
||||||
|
|
||||||
@@ -107,6 +125,11 @@ public class RepoAdminServiceImplTest extends TestCase
|
|||||||
dictionaryService = (DictionaryService) ctx.getBean("DictionaryService");
|
dictionaryService = (DictionaryService) ctx.getBean("DictionaryService");
|
||||||
transactionService = (TransactionService) ctx.getBean("TransactionService");
|
transactionService = (TransactionService) ctx.getBean("TransactionService");
|
||||||
|
|
||||||
|
nodeService = (NodeService) ctx.getBean("NodeService");
|
||||||
|
contentService = (ContentService) ctx.getBean("ContentService");
|
||||||
|
searchService = (SearchService) ctx.getBean("SearchService");
|
||||||
|
namespaceService = (NamespaceService) ctx.getBean("NamespaceService");
|
||||||
|
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,9 +148,140 @@ public class RepoAdminServiceImplTest extends TestCase
|
|||||||
// Test custom model management
|
// Test custom model management
|
||||||
//
|
//
|
||||||
|
|
||||||
public void testSimpleDynamicModel() throws Exception
|
public void testSimpleDynamicModelViaNodeService() throws Exception
|
||||||
{
|
{
|
||||||
final int X = 0;
|
final String X = "A";
|
||||||
|
final String modelFileName = modelPrefix+X+".xml";
|
||||||
|
final QName typeName = QName.createQName("{http://www.alfresco.org/test/testmodel"+X+"/1.0}base");
|
||||||
|
final QName modelName = QName.createQName("{http://www.alfresco.org/test/testmodel"+X+"/1.0}testModel"+X);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (isModelDeployed(modelFileName))
|
||||||
|
{
|
||||||
|
// undeploy model
|
||||||
|
repoAdminService.undeployModel(modelFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreRef storeRef = StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
assertNull(dictionaryService.getClass(typeName));
|
||||||
|
|
||||||
|
final int defaultModelCnt = dictionaryService.getAllModels().size();
|
||||||
|
|
||||||
|
// deploy custom model
|
||||||
|
String model = MODEL_MKR_XML.replace(MKR, X+"");
|
||||||
|
InputStream modelStream = new ByteArrayInputStream(model.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, "/app:company_home/app:dictionary/app:models", null, namespaceService, false);
|
||||||
|
assertEquals(1, nodeRefs.size());
|
||||||
|
NodeRef modelsNodeRef = nodeRefs.get(0);
|
||||||
|
|
||||||
|
// create model node
|
||||||
|
|
||||||
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
|
contentProps.put(ContentModel.PROP_NAME, modelFileName);
|
||||||
|
|
||||||
|
NodeRef model1 = nodeService.createNode(
|
||||||
|
modelsNodeRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
modelName,
|
||||||
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
|
contentProps).getChildRef();
|
||||||
|
|
||||||
|
// add titled aspect (for Web Client display)
|
||||||
|
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
|
||||||
|
titledProps.put(ContentModel.PROP_TITLE, modelFileName);
|
||||||
|
titledProps.put(ContentModel.PROP_DESCRIPTION, modelFileName);
|
||||||
|
nodeService.addAspect(model1, ContentModel.ASPECT_TITLED, titledProps);
|
||||||
|
|
||||||
|
ContentWriter writer = contentService.getWriter(model1, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
writer.putContent(modelStream); // also invokes policies for DictionaryModelType - e.g. onContentUpdate
|
||||||
|
modelStream.close();
|
||||||
|
|
||||||
|
// activate the model
|
||||||
|
nodeService.setProperty(model1, ContentModel.PROP_MODEL_ACTIVE, new Boolean(true));
|
||||||
|
|
||||||
|
assertEquals(defaultModelCnt+1, dictionaryService.getAllModels().size());
|
||||||
|
|
||||||
|
ClassDefinition myType = dictionaryService.getClass(typeName);
|
||||||
|
assertNotNull(myType);
|
||||||
|
assertEquals(modelName, myType.getModel().getName());
|
||||||
|
|
||||||
|
// create node with custom type
|
||||||
|
NodeRef node1 = nodeService.createNode(
|
||||||
|
rootNodeRef,
|
||||||
|
ContentModel.ASSOC_CHILDREN,
|
||||||
|
QName.createQName("http://www.alfresco.org/model/system/1.0", "node1"),
|
||||||
|
typeName,
|
||||||
|
null).getChildRef();
|
||||||
|
|
||||||
|
// try to delete the model
|
||||||
|
try
|
||||||
|
{
|
||||||
|
nodeService.deleteNode(model1);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (AlfrescoRuntimeException are)
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
assertTrue(are.getMessage().contains("Failed to validate model delete"));
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeService.deleteNode(node1);
|
||||||
|
assertFalse(nodeService.exists(node1));
|
||||||
|
|
||||||
|
NodeRef archiveRootNode = nodeService.getStoreArchiveNode(storeRef);
|
||||||
|
NodeRef archiveNode1 = new NodeRef(archiveRootNode.getStoreRef(), node1.getId());
|
||||||
|
assertTrue(nodeService.exists(archiveNode1));
|
||||||
|
|
||||||
|
// try to delete the model
|
||||||
|
try
|
||||||
|
{
|
||||||
|
nodeService.deleteNode(model1);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (AlfrescoRuntimeException are)
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
assertTrue(are.getMessage().contains("Failed to validate model delete"));
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeService.deleteNode(archiveNode1);
|
||||||
|
assertFalse(nodeService.exists(archiveNode1));
|
||||||
|
|
||||||
|
// delete model
|
||||||
|
nodeService.deleteNode(model1);
|
||||||
|
|
||||||
|
assertEquals(defaultModelCnt, dictionaryService.getAllModels().size());
|
||||||
|
assertNull(dictionaryService.getClass(typeName));
|
||||||
|
|
||||||
|
NodeRef archiveModel1 = new NodeRef(archiveRootNode.getStoreRef(), model1.getId());
|
||||||
|
|
||||||
|
// restore model
|
||||||
|
nodeService.restoreNode(archiveModel1, null, null, null);
|
||||||
|
|
||||||
|
assertEquals(defaultModelCnt+1, dictionaryService.getAllModels().size());
|
||||||
|
assertNotNull(dictionaryService.getClass(typeName));
|
||||||
|
|
||||||
|
// delete for good
|
||||||
|
nodeService.deleteNode(model1);
|
||||||
|
nodeService.deleteNode(archiveModel1);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testSimpleDynamicModelViaRepoAdminService() throws Exception
|
||||||
|
{
|
||||||
|
final String X = "B";
|
||||||
final String modelFileName = modelPrefix+X+".xml";
|
final String modelFileName = modelPrefix+X+".xml";
|
||||||
final QName typeName = QName.createQName("{http://www.alfresco.org/test/testmodel"+X+"/1.0}base");
|
final QName typeName = QName.createQName("{http://www.alfresco.org/test/testmodel"+X+"/1.0}base");
|
||||||
final QName modelName = QName.createQName("{http://www.alfresco.org/test/testmodel"+X+"/1.0}testModel"+X);
|
final QName modelName = QName.createQName("{http://www.alfresco.org/test/testmodel"+X+"/1.0}testModel"+X);
|
||||||
@@ -180,6 +334,7 @@ public class RepoAdminServiceImplTest extends TestCase
|
|||||||
{
|
{
|
||||||
// expected
|
// expected
|
||||||
assertTrue(are.getMessage().contains("Model deactivation failed"));
|
assertTrue(are.getMessage().contains("Model deactivation failed"));
|
||||||
|
assertTrue(are.getCause().getMessage().contains("is already deactivated"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-activate model
|
// re-activate model
|
||||||
@@ -202,9 +357,57 @@ public class RepoAdminServiceImplTest extends TestCase
|
|||||||
{
|
{
|
||||||
// expected
|
// expected
|
||||||
assertTrue(are.getMessage().contains("Model activation failed"));
|
assertTrue(are.getMessage().contains("Model activation failed"));
|
||||||
|
assertTrue(are.getCause().getMessage().contains("is already activated"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// undeploy model
|
StoreRef storeRef = StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
// create node with custom type
|
||||||
|
NodeRef node1 = nodeService.createNode(
|
||||||
|
rootNodeRef,
|
||||||
|
ContentModel.ASSOC_CHILDREN,
|
||||||
|
QName.createQName("http://www.alfresco.org/model/system/1.0", "node1"),
|
||||||
|
typeName,
|
||||||
|
null).getChildRef();
|
||||||
|
|
||||||
|
// try to undeploy model
|
||||||
|
try
|
||||||
|
{
|
||||||
|
repoAdminService.undeployModel(modelFileName);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (AlfrescoRuntimeException are)
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
assertTrue(are.getMessage().contains("Model undeployment failed"));
|
||||||
|
assertTrue(are.getCause().getMessage().contains("Failed to validate model delete"));
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeService.deleteNode(node1);
|
||||||
|
assertFalse(nodeService.exists(node1));
|
||||||
|
|
||||||
|
NodeRef archiveRootNode = nodeService.getStoreArchiveNode(storeRef);
|
||||||
|
NodeRef archiveNode1 = new NodeRef(archiveRootNode.getStoreRef(), node1.getId());
|
||||||
|
assertTrue(nodeService.exists(archiveNode1));
|
||||||
|
|
||||||
|
// try to undeploy model
|
||||||
|
try
|
||||||
|
{
|
||||||
|
repoAdminService.undeployModel(modelFileName);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (AlfrescoRuntimeException are)
|
||||||
|
{
|
||||||
|
// expected
|
||||||
|
assertTrue(are.getMessage().contains("Model undeployment failed"));
|
||||||
|
assertTrue(are.getCause().getMessage().contains("Failed to validate model delete"));
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeService.deleteNode(archiveNode1);
|
||||||
|
assertFalse(nodeService.exists(archiveNode1));
|
||||||
|
|
||||||
|
// undeploy
|
||||||
repoAdminService.undeployModel(modelFileName);
|
repoAdminService.undeployModel(modelFileName);
|
||||||
|
|
||||||
assertFalse(isModelDeployed(modelFileName));
|
assertFalse(isModelDeployed(modelFileName));
|
||||||
@@ -221,6 +424,7 @@ public class RepoAdminServiceImplTest extends TestCase
|
|||||||
{
|
{
|
||||||
// expected
|
// expected
|
||||||
assertTrue(are.getMessage().contains("Model undeployment failed"));
|
assertTrue(are.getMessage().contains("Model undeployment failed"));
|
||||||
|
assertTrue(are.getCause().getMessage().contains("Could not find custom model"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@@ -123,6 +123,11 @@ public class DictionaryBootstrap implements DictionaryListener
|
|||||||
{
|
{
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("onDictionaryInit: ["+Thread.currentThread()+"]");
|
||||||
|
}
|
||||||
|
|
||||||
Collection<QName> modelsBefore = dictionaryDAO.getModels(); // note: on first bootstrap will init empty dictionary
|
Collection<QName> modelsBefore = dictionaryDAO.getModels(); // note: on first bootstrap will init empty dictionary
|
||||||
int modelsBeforeCnt = (modelsBefore != null ? modelsBefore.size() : 0);
|
int modelsBeforeCnt = (modelsBefore != null ? modelsBefore.size() : 0);
|
||||||
|
|
||||||
@@ -158,7 +163,7 @@ public class DictionaryBootstrap implements DictionaryListener
|
|||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Model count: before="+modelsBeforeCnt+", load="+models.size()+", after="+modelsAfterCnt+" in "+(System.currentTimeMillis()-startTime)+" msecs");
|
logger.debug("Model count: before="+modelsBeforeCnt+", load="+models.size()+", after="+modelsAfterCnt+" in "+(System.currentTimeMillis()-startTime)+" msecs ["+Thread.currentThread()+"]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -162,8 +162,8 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy();
|
destroy();
|
||||||
init();
|
init();
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("... resetting dictionary completed");
|
logger.debug("... resetting dictionary completed");
|
||||||
@@ -175,17 +175,19 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
{
|
{
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Init Dictionary: ["+Thread.currentThread()+"] "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return AuthenticationUtil.runAs(new RunAsWork<DictionaryRegistry>()
|
return AuthenticationUtil.runAs(new RunAsWork<DictionaryRegistry>()
|
||||||
{
|
{
|
||||||
public DictionaryRegistry doWork()
|
public DictionaryRegistry doWork()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create threadlocal, if needed
|
|
||||||
createDataDictionaryLocal(tenantDomain);
|
|
||||||
|
|
||||||
DictionaryRegistry dictionaryRegistry = initDictionaryRegistry(tenantDomain);
|
DictionaryRegistry dictionaryRegistry = initDictionaryRegistry(tenantDomain);
|
||||||
|
|
||||||
if (dictionaryRegistry == null)
|
if (dictionaryRegistry == null)
|
||||||
@@ -221,24 +223,32 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
readLock.unlock();
|
readLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
|
}, tenantService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isInfoEnabled())
|
||||||
{
|
{
|
||||||
logger.info("Init Dictionary: model count = "+(getModels() != null ? getModels().size() : 0) +" in "+(System.currentTimeMillis()-startTime)+" msecs "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
logger.info("Init Dictionary: model count = "+(getModels() != null ? getModels().size() : 0) +" in "+(System.currentTimeMillis()-startTime)+" msecs ["+Thread.currentThread()+"] "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DictionaryRegistry initDictionaryRegistry(String tenantDomain)
|
private DictionaryRegistry initDictionaryRegistry(String tenantDomain)
|
||||||
{
|
{
|
||||||
getDictionaryRegistry(tenantDomain).setCompiledModels(new HashMap<QName,CompiledModel>());
|
// create threadlocal, if needed
|
||||||
getDictionaryRegistry(tenantDomain).setUriToModels(new HashMap<String, List<CompiledModel>>());
|
DictionaryRegistry dictionaryRegistry = createDataDictionaryLocal(tenantDomain);
|
||||||
|
|
||||||
// initialise empty dictionary & namespaces
|
dictionaryRegistry.setCompiledModels(new HashMap<QName,CompiledModel>());
|
||||||
|
dictionaryRegistry.setUriToModels(new HashMap<String, List<CompiledModel>>());
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("Empty dictionary initialised: "+dictionaryRegistry+" - "+defaultDictionaryRegistryThreadLocal+" ["+Thread.currentThread()+"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialise empty namespaces
|
||||||
namespaceDAO.init();
|
namespaceDAO.init();
|
||||||
|
|
||||||
// populate the dictionary based on registered sources
|
// populate the dictionary based on registered sources
|
||||||
@@ -253,7 +263,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
dictionaryListener.afterDictionaryInit();
|
dictionaryListener.afterDictionaryInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDictionaryRegistryLocal(tenantDomain);
|
return dictionaryRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
@@ -1018,7 +1028,7 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create threadlocal
|
// create threadlocal
|
||||||
private void createDataDictionaryLocal(String tenantDomain)
|
private DictionaryRegistry createDataDictionaryLocal(String tenantDomain)
|
||||||
{
|
{
|
||||||
// create threadlocal, if needed
|
// create threadlocal, if needed
|
||||||
DictionaryRegistry dictionaryRegistry = getDictionaryRegistryLocal(tenantDomain);
|
DictionaryRegistry dictionaryRegistry = getDictionaryRegistryLocal(tenantDomain);
|
||||||
@@ -1035,6 +1045,8 @@ public class DictionaryDAOImpl implements DictionaryDAO
|
|||||||
dictionaryRegistryThreadLocal.set(dictionaryRegistry);
|
dictionaryRegistryThreadLocal.set(dictionaryRegistry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dictionaryRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get threadlocal
|
// get threadlocal
|
||||||
|
@@ -92,9 +92,6 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
/** Key to the removed "workingcopy" aspect */
|
/** Key to the removed "workingcopy" aspect */
|
||||||
private static final String KEY_WORKING_COPY = "dictionaryModelType.workingCopy";
|
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 */
|
/** The dictionary DAO */
|
||||||
private DictionaryDAO dictionaryDAO;
|
private DictionaryDAO dictionaryDAO;
|
||||||
|
|
||||||
@@ -235,37 +232,37 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
// Register interest in the onContentUpdate policy for the dictionary model type
|
// Register interest in the onContentUpdate policy for the dictionary model type
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
ContentServicePolicies.ON_CONTENT_UPDATE,
|
ContentServicePolicies.ON_CONTENT_UPDATE,
|
||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "onContentUpdate"));
|
new JavaBehaviour(this, "onContentUpdate"));
|
||||||
|
|
||||||
// Register interest in the onUpdateProperties policy for the dictionary model type
|
// Register interest in the onUpdateProperties policy for the dictionary model type
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
|
||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "onUpdateProperties"));
|
new JavaBehaviour(this, "onUpdateProperties"));
|
||||||
|
|
||||||
// Register interest in the beforeDeleteNode policy for the dictionary model type
|
// Register interest in the beforeDeleteNode policy for the dictionary model type
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"),
|
||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "beforeDeleteNode"));
|
new JavaBehaviour(this, "beforeDeleteNode"));
|
||||||
|
|
||||||
// Register interest in the onDeleteNode policy for the dictionary model type
|
// Register interest in the onDeleteNode policy for the dictionary model type
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"),
|
||||||
ContentModel.TYPE_DICTIONARY_MODEL,
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
new JavaBehaviour(this, "onDeleteNode"));
|
new JavaBehaviour(this, "onDeleteNode"));
|
||||||
|
|
||||||
// Register interest in the onRemoveAspect policy
|
// Register interest in the onRemoveAspect policy
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"),
|
||||||
this,
|
this,
|
||||||
new JavaBehaviour(this, "onRemoveAspect"));
|
new JavaBehaviour(this, "onRemoveAspect"));
|
||||||
|
|
||||||
// Register interest in the onCreateNode policy
|
// Register interest in the onCreateNode policy
|
||||||
policyComponent.bindClassBehaviour(
|
policyComponent.bindClassBehaviour(
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
|
||||||
this,
|
this,
|
||||||
new JavaBehaviour(this, "onCreateNode"));
|
new JavaBehaviour(this, "onCreateNode"));
|
||||||
|
|
||||||
// Create the transaction listener
|
// Create the transaction listener
|
||||||
@@ -349,12 +346,6 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
{
|
{
|
||||||
AlfrescoTransactionSupport.bindResource(KEY_WORKING_COPY, nodeRef);
|
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")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -367,17 +358,10 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
workingCopy = true;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isVersionNode = nodeRef.getStoreRef().getIdentifier().equals(Version2Model.STORE_ID);
|
boolean isVersionNode = nodeRef.getStoreRef().getIdentifier().equals(Version2Model.STORE_ID);
|
||||||
|
|
||||||
// Ignore if the node is a working copy, archived or version node
|
// Ignore if the node is a working copy or version node
|
||||||
if (! (workingCopy || archived || isVersionNode))
|
if (! (workingCopy || isVersionNode))
|
||||||
{
|
{
|
||||||
QName modelName = (QName)this.nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_NAME);
|
QName modelName = (QName)this.nodeService.getProperty(nodeRef, ContentModel.PROP_MODEL_NAME);
|
||||||
|
|
||||||
@@ -407,7 +391,7 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
{
|
{
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
{
|
{
|
||||||
logger.trace("beforeDeleteNode: nodeRef="+nodeRef+ " ignored ("+(workingCopy ? " workingCopy " : "")+(archived ? " archived " : "")+(isVersionNode ? " isVersionNode " : "")+") ["+AlfrescoTransactionSupport.getTransactionId()+"]");
|
logger.trace("beforeDeleteNode: nodeRef="+nodeRef+ " ignored ("+(workingCopy ? " workingCopy " : "")+(isVersionNode ? " isVersionNode " : "")+") ["+AlfrescoTransactionSupport.getTransactionId()+"]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -606,8 +590,8 @@ public class DictionaryModelType implements ContentServicePolicies.OnContentUpda
|
|||||||
isActive = value.booleanValue();
|
isActive = value.booleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore if the node is a working copy or archived
|
// Ignore if the node is a working copy
|
||||||
if (! (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) || nodeService.hasAspect(nodeRef, ContentModel.ASPECT_ARCHIVED)))
|
if (! (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY)))
|
||||||
{
|
{
|
||||||
if (isActive == true)
|
if (isActive == true)
|
||||||
{
|
{
|
||||||
|
@@ -33,7 +33,6 @@ import org.alfresco.repo.i18n.MessageService;
|
|||||||
import org.alfresco.repo.tenant.TenantAdminService;
|
import org.alfresco.repo.tenant.TenantAdminService;
|
||||||
import org.alfresco.repo.tenant.TenantDeployer;
|
import org.alfresco.repo.tenant.TenantDeployer;
|
||||||
import org.alfresco.repo.tenant.TenantService;
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
|
||||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
@@ -211,6 +210,11 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme
|
|||||||
{
|
{
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("onDictionaryInit: ["+Thread.currentThread()+"]");
|
||||||
|
}
|
||||||
|
|
||||||
Collection<QName> modelsBefore = dictionaryDAO.getModels();
|
Collection<QName> modelsBefore = dictionaryDAO.getModels();
|
||||||
int modelsBeforeCnt = (modelsBefore != null ? modelsBefore.size() : 0);
|
int modelsBeforeCnt = (modelsBefore != null ? modelsBefore.size() : 0);
|
||||||
|
|
||||||
@@ -220,6 +224,11 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme
|
|||||||
{
|
{
|
||||||
Map<String, Pair<RepositoryLocation, M2Model>> modelMap = new HashMap<String, Pair<RepositoryLocation, M2Model>>();
|
Map<String, Pair<RepositoryLocation, M2Model>> modelMap = new HashMap<String, Pair<RepositoryLocation, M2Model>>();
|
||||||
|
|
||||||
|
if (logger.isTraceEnabled())
|
||||||
|
{
|
||||||
|
logger.trace("onDictionaryInit: locations="+this.repositoryModelsLocations);
|
||||||
|
}
|
||||||
|
|
||||||
// Register the models found in the repository
|
// Register the models found in the repository
|
||||||
|
|
||||||
for (RepositoryLocation repositoryLocation : this.repositoryModelsLocations)
|
for (RepositoryLocation repositoryLocation : this.repositoryModelsLocations)
|
||||||
@@ -289,14 +298,14 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme
|
|||||||
if (modelsAfterCnt != (modelsBeforeCnt + loadedModels.size()))
|
if (modelsAfterCnt != (modelsBeforeCnt + loadedModels.size()))
|
||||||
{
|
{
|
||||||
String tenantDomain = tenantAdminService.getCurrentUserDomain();
|
String tenantDomain = tenantAdminService.getCurrentUserDomain();
|
||||||
logger.warn("Model count: before="+modelsBeforeCnt+", load="+loadedModels.size()+", after="+modelsAfterCnt+" ["+AlfrescoTransactionSupport.getTransactionId()+"] in "+(System.currentTimeMillis()-startTime)+" msecs "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
logger.warn("Model count: before="+modelsBeforeCnt+", load="+loadedModels.size()+", after="+modelsAfterCnt+" in "+(System.currentTimeMillis()-startTime)+" msecs ["+Thread.currentThread()+"] "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
String tenantDomain = tenantAdminService.getCurrentUserDomain();
|
String tenantDomain = tenantAdminService.getCurrentUserDomain();
|
||||||
logger.debug("Model count: before="+modelsBeforeCnt+", load="+loadedModels.size()+", after="+modelsAfterCnt+" ["+AlfrescoTransactionSupport.getTransactionId()+"] in "+(System.currentTimeMillis()-startTime)+" msecs "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
logger.debug("Model count: before="+modelsBeforeCnt+", load="+loadedModels.size()+", after="+modelsAfterCnt+" in "+(System.currentTimeMillis()-startTime)+" msecs ["+Thread.currentThread()+"] "+(tenantDomain.equals(TenantService.DEFAULT_DOMAIN) ? "" : " (Tenant: "+tenantDomain+")"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -64,6 +64,8 @@ public interface NamespaceDAO extends NamespacePrefixResolver
|
|||||||
*/
|
*/
|
||||||
public void init();
|
public void init();
|
||||||
|
|
||||||
|
public void afterDictionaryInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy Namespaces
|
* Destroy Namespaces
|
||||||
*/
|
*/
|
||||||
|
@@ -38,7 +38,7 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
/**
|
/**
|
||||||
* Simple in-memory namespace DAO
|
* Simple in-memory namespace DAO
|
||||||
*/
|
*/
|
||||||
public class NamespaceDAOImpl implements NamespaceDAO
|
public class NamespaceDAOImpl implements NamespaceDAO, DictionaryListener
|
||||||
{
|
{
|
||||||
private static final Log logger = LogFactory.getLog(NamespaceDAOImpl.class);
|
private static final Log logger = LogFactory.getLog(NamespaceDAOImpl.class);
|
||||||
|
|
||||||
@@ -74,15 +74,78 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
public void registerDictionary(DictionaryDAO dictionaryDAO)
|
public void registerDictionary(DictionaryDAO dictionaryDAO)
|
||||||
{
|
{
|
||||||
this.dictionaryDAO = dictionaryDAO;
|
this.dictionaryDAO = dictionaryDAO;
|
||||||
|
this.dictionaryDAO.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void afterDictionaryDestroy()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDictionaryInit()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete the initialisation
|
||||||
|
*/
|
||||||
|
public void afterDictionaryInit()
|
||||||
|
{
|
||||||
|
String tenantDomain = getTenantDomain();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NamespaceRegistry namespaceRegistry = getNamespaceRegistryLocal(tenantDomain);
|
||||||
|
|
||||||
|
if (namespaceRegistry == null)
|
||||||
|
{
|
||||||
|
// unexpected
|
||||||
|
throw new AlfrescoRuntimeException("Failed to init namespaceRegistry " + tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
writeLock.lock();
|
||||||
|
namespaceRegistryCache.put(tenantDomain, namespaceRegistry);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
writeLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
readLock.lock();
|
||||||
|
if (namespaceRegistryCache.get(tenantDomain) != null)
|
||||||
|
{
|
||||||
|
removeNamespaceLocal(tenantDomain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise empty namespaces
|
* Initialise empty namespaces
|
||||||
*/
|
*/
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
initNamespace(getTenantDomain());
|
String tenantDomain = getTenantDomain();
|
||||||
|
NamespaceRegistry namespaceRegistry = initNamespaceRegistry(tenantDomain);
|
||||||
|
|
||||||
|
if (namespaceRegistry == null)
|
||||||
|
{
|
||||||
|
// unexpected
|
||||||
|
throw new AlfrescoRuntimeException("Failed to init namespaceRegistry " + tenantDomain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,60 +191,20 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
return namespaceRegistry;
|
return namespaceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NamespaceRegistry initNamespace(String tenantDomain)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
createNamespaceLocal(tenantDomain);
|
|
||||||
|
|
||||||
NamespaceRegistry namespaceRegistry = initNamespaceRegistry(tenantDomain);
|
|
||||||
|
|
||||||
if (namespaceRegistry == null)
|
|
||||||
{
|
|
||||||
// unexpected
|
|
||||||
throw new AlfrescoRuntimeException("Failed to init namespaceRegistry " + tenantDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
writeLock.lock();
|
|
||||||
namespaceRegistryCache.put(tenantDomain, namespaceRegistry);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
writeLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return namespaceRegistry;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
readLock.lock();
|
|
||||||
if (namespaceRegistryCache.get(tenantDomain) != null)
|
|
||||||
{
|
|
||||||
removeNamespaceLocal(tenantDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
readLock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private NamespaceRegistry initNamespaceRegistry(String tenantDomain)
|
private NamespaceRegistry initNamespaceRegistry(String tenantDomain)
|
||||||
{
|
{
|
||||||
getNamespaceRegistry(tenantDomain).setUrisCache(new ArrayList<String>());
|
// create threadlocal, if needed
|
||||||
getNamespaceRegistry(tenantDomain).setPrefixesCache(new HashMap<String, String>());
|
NamespaceRegistry namespaceRegistry = createNamespaceLocal(tenantDomain);
|
||||||
|
|
||||||
|
namespaceRegistry.setUrisCache(new ArrayList<String>());
|
||||||
|
namespaceRegistry.setPrefixesCache(new HashMap<String, String>());
|
||||||
|
|
||||||
if (logger.isTraceEnabled())
|
if (logger.isTraceEnabled())
|
||||||
{
|
{
|
||||||
logger.trace("Empty namespaces initialised");
|
logger.trace("Empty namespaces initialised: "+namespaceRegistry+" - "+namespaceRegistryThreadLocal+" ["+Thread.currentThread()+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
return getNamespaceRegistryLocal(tenantDomain);
|
return namespaceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -242,7 +265,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
// overridden, hence skip this default prefix
|
// overridden, hence skip this default prefix
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
prefixesFiltered.add(prefix);
|
prefixesFiltered.add(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// default (non-overridden) + tenant-specific
|
// default (non-overridden) + tenant-specific
|
||||||
@@ -427,7 +450,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create threadlocal
|
// create threadlocal
|
||||||
private void createNamespaceLocal(String tenantDomain)
|
private NamespaceRegistry createNamespaceLocal(String tenantDomain)
|
||||||
{
|
{
|
||||||
// create threadlocal, if needed
|
// create threadlocal, if needed
|
||||||
NamespaceRegistry namespaceRegistry = getNamespaceRegistryLocal(tenantDomain);
|
NamespaceRegistry namespaceRegistry = getNamespaceRegistryLocal(tenantDomain);
|
||||||
@@ -435,17 +458,17 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
{
|
{
|
||||||
namespaceRegistry = new NamespaceRegistry(tenantDomain);
|
namespaceRegistry = new NamespaceRegistry(tenantDomain);
|
||||||
|
|
||||||
if (! tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
if (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))
|
||||||
|
{
|
||||||
|
defaultNamespaceRegistryThreadLocal.set(namespaceRegistry);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
namespaceRegistryThreadLocal.set(namespaceRegistry);
|
namespaceRegistryThreadLocal.set(namespaceRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultNamespaceRegistryThreadLocal.get() == null)
|
|
||||||
{
|
|
||||||
namespaceRegistry = new NamespaceRegistry(TenantService.DEFAULT_DOMAIN);
|
|
||||||
defaultNamespaceRegistryThreadLocal.set(namespaceRegistry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return namespaceRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get threadlocal
|
// get threadlocal
|
||||||
@@ -466,7 +489,7 @@ public class NamespaceDAOImpl implements NamespaceDAO
|
|||||||
if ((namespaceRegistry != null) && (tenantDomain.equals(namespaceRegistry.getTenantDomain())))
|
if ((namespaceRegistry != null) && (tenantDomain.equals(namespaceRegistry.getTenantDomain())))
|
||||||
{
|
{
|
||||||
return namespaceRegistry; // return threadlocal, if set
|
return namespaceRegistry; // return threadlocal, if set
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
package org.alfresco.repo.node;
|
package org.alfresco.repo.node;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -52,6 +53,7 @@ import org.alfresco.repo.policy.AssociationPolicyDelegate;
|
|||||||
import org.alfresco.repo.policy.ClassPolicyDelegate;
|
import org.alfresco.repo.policy.ClassPolicyDelegate;
|
||||||
import org.alfresco.repo.policy.PolicyComponent;
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
import org.alfresco.repo.search.Indexer;
|
import org.alfresco.repo.search.Indexer;
|
||||||
|
import org.alfresco.repo.tenant.TenantService;
|
||||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
@@ -95,6 +97,8 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
private PolicyComponent policyComponent;
|
private PolicyComponent policyComponent;
|
||||||
protected DictionaryService dictionaryService;
|
protected DictionaryService dictionaryService;
|
||||||
protected TransactionService transactionService;
|
protected TransactionService transactionService;
|
||||||
|
protected TenantService tenantService;
|
||||||
|
protected List<String> storesToIgnorePolicies = new ArrayList<String>(0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Policy delegates
|
* Policy delegates
|
||||||
@@ -144,6 +148,16 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
{
|
{
|
||||||
this.transactionService = transactionService;
|
this.transactionService = transactionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTenantService(TenantService tenantService)
|
||||||
|
{
|
||||||
|
this.tenantService = tenantService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoresToIgnorePolicies(List<String> storesToIgnorePolicies)
|
||||||
|
{
|
||||||
|
this.storesToIgnorePolicies = storesToIgnorePolicies;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks equality by type and uuid
|
* Checks equality by type and uuid
|
||||||
@@ -203,13 +217,28 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
onCreateAssociationDelegate = policyComponent.registerAssociationPolicy(NodeServicePolicies.OnCreateAssociationPolicy.class);
|
onCreateAssociationDelegate = policyComponent.registerAssociationPolicy(NodeServicePolicies.OnCreateAssociationPolicy.class);
|
||||||
onDeleteAssociationDelegate = policyComponent.registerAssociationPolicy(NodeServicePolicies.OnDeleteAssociationPolicy.class);
|
onDeleteAssociationDelegate = policyComponent.registerAssociationPolicy(NodeServicePolicies.OnDeleteAssociationPolicy.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean ignorePolicy(StoreRef storeRef)
|
||||||
|
{
|
||||||
|
return (storesToIgnorePolicies.contains(tenantService.getBaseName(storeRef).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ignorePolicy(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
return (storesToIgnorePolicies.contains(tenantService.getBaseName(nodeRef.getStoreRef()).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NodeServicePolicies.BeforeCreateStorePolicy#beforeCreateStore(QName,
|
* @see NodeServicePolicies.BeforeCreateStorePolicy#beforeCreateStore(QName,
|
||||||
* StoreRef)
|
* StoreRef)
|
||||||
*/
|
*/
|
||||||
protected void invokeBeforeCreateStore(QName nodeTypeQName, StoreRef storeRef)
|
protected void invokeBeforeCreateStore(QName nodeTypeQName, StoreRef storeRef)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(storeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NodeServicePolicies.BeforeCreateStorePolicy policy = this.beforeCreateStoreDelegate.get(nodeTypeQName);
|
NodeServicePolicies.BeforeCreateStorePolicy policy = this.beforeCreateStoreDelegate.get(nodeTypeQName);
|
||||||
policy.beforeCreateStore(nodeTypeQName, storeRef);
|
policy.beforeCreateStore(nodeTypeQName, storeRef);
|
||||||
}
|
}
|
||||||
@@ -219,6 +248,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeOnCreateStore(NodeRef rootNodeRef)
|
protected void invokeOnCreateStore(NodeRef rootNodeRef)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(rootNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(rootNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(rootNodeRef);
|
||||||
// execute policy for node type and aspects
|
// execute policy for node type and aspects
|
||||||
@@ -232,6 +266,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeCreateNode(NodeRef parentNodeRef, QName assocTypeQName, QName assocQName, QName childNodeTypeQName)
|
protected void invokeBeforeCreateNode(NodeRef parentNodeRef, QName assocTypeQName, QName assocQName, QName childNodeTypeQName)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// execute policy for node type
|
// execute policy for node type
|
||||||
NodeServicePolicies.BeforeCreateNodePolicy policy = beforeCreateNodeDelegate.get(childNodeTypeQName);
|
NodeServicePolicies.BeforeCreateNodePolicy policy = beforeCreateNodeDelegate.get(childNodeTypeQName);
|
||||||
policy.beforeCreateNode(parentNodeRef, assocTypeQName, assocQName, childNodeTypeQName);
|
policy.beforeCreateNode(parentNodeRef, assocTypeQName, assocQName, childNodeTypeQName);
|
||||||
@@ -243,6 +282,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
protected void invokeOnCreateNode(ChildAssociationRef childAssocRef)
|
protected void invokeOnCreateNode(ChildAssociationRef childAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef childNodeRef = childAssocRef.getChildRef();
|
NodeRef childNodeRef = childAssocRef.getChildRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(childNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(childNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(childNodeRef);
|
||||||
// execute policy for node type and aspects
|
// execute policy for node type and aspects
|
||||||
@@ -256,6 +301,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
protected void invokeOnMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef)
|
protected void invokeOnMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef childNodeRef = newChildAssocRef.getChildRef();
|
NodeRef childNodeRef = newChildAssocRef.getChildRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(childNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(childNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(childNodeRef);
|
||||||
// execute policy for node type and aspects
|
// execute policy for node type and aspects
|
||||||
@@ -268,6 +319,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeUpdateNode(NodeRef nodeRef)
|
protected void invokeBeforeUpdateNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(nodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(nodeRef);
|
||||||
// execute policy for node type and aspects
|
// execute policy for node type and aspects
|
||||||
@@ -280,6 +336,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeOnUpdateNode(NodeRef nodeRef)
|
protected void invokeOnUpdateNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(nodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(nodeRef);
|
||||||
// execute policy for node type and aspects
|
// execute policy for node type and aspects
|
||||||
@@ -295,6 +356,10 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
Map<QName, Serializable> before,
|
Map<QName, Serializable> before,
|
||||||
Map<QName, Serializable> after)
|
Map<QName, Serializable> after)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Some logging so we can see which properties have been modified
|
// Some logging so we can see which properties have been modified
|
||||||
if (logger.isDebugEnabled() == true)
|
if (logger.isDebugEnabled() == true)
|
||||||
@@ -344,6 +409,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeDeleteNode(NodeRef nodeRef)
|
protected void invokeBeforeDeleteNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(nodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(nodeRef);
|
||||||
// execute policy for node type and aspects
|
// execute policy for node type and aspects
|
||||||
@@ -356,14 +426,30 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeOnDeleteNode(ChildAssociationRef childAssocRef, QName childNodeTypeQName, Set<QName> childAspectQnames, boolean isArchivedNode)
|
protected void invokeOnDeleteNode(ChildAssociationRef childAssocRef, QName childNodeTypeQName, Set<QName> childAspectQnames, boolean isArchivedNode)
|
||||||
{
|
{
|
||||||
// get qnames to invoke against
|
NodeRef childNodeRef = childAssocRef.getChildRef();
|
||||||
Set<QName> qnames = new HashSet<QName>(childAspectQnames.size() + 1);
|
|
||||||
qnames.addAll(childAspectQnames);
|
|
||||||
qnames.add(childNodeTypeQName);
|
|
||||||
|
|
||||||
// execute policy for node type and aspects
|
Set<QName> qnames = null;
|
||||||
NodeServicePolicies.OnDeleteNodePolicy policy = onDeleteNodeDelegate.get(childAssocRef.getChildRef(), qnames);
|
|
||||||
policy.onDeleteNode(childAssocRef, isArchivedNode);
|
if (ignorePolicy(childNodeRef))
|
||||||
|
{
|
||||||
|
// special case
|
||||||
|
qnames = new HashSet<QName>(1);
|
||||||
|
qnames.add(ContentModel.ASPECT_VERSIONABLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get qnames to invoke against
|
||||||
|
qnames = new HashSet<QName>(childAspectQnames.size() + 1);
|
||||||
|
qnames.addAll(childAspectQnames);
|
||||||
|
qnames.add(childNodeTypeQName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qnames != null)
|
||||||
|
{
|
||||||
|
// execute policy for node type and aspects
|
||||||
|
NodeServicePolicies.OnDeleteNodePolicy policy = onDeleteNodeDelegate.get(childAssocRef.getChildRef(), qnames);
|
||||||
|
policy.onDeleteNode(childAssocRef, isArchivedNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -372,6 +458,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeAddAspect(NodeRef nodeRef, QName aspectTypeQName)
|
protected void invokeBeforeAddAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NodeServicePolicies.BeforeAddAspectPolicy policy = beforeAddAspectDelegate.get(nodeRef, aspectTypeQName);
|
NodeServicePolicies.BeforeAddAspectPolicy policy = beforeAddAspectDelegate.get(nodeRef, aspectTypeQName);
|
||||||
policy.beforeAddAspect(nodeRef, aspectTypeQName);
|
policy.beforeAddAspect(nodeRef, aspectTypeQName);
|
||||||
}
|
}
|
||||||
@@ -381,6 +472,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeOnAddAspect(NodeRef nodeRef, QName aspectTypeQName)
|
protected void invokeOnAddAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NodeServicePolicies.OnAddAspectPolicy policy = onAddAspectDelegate.get(nodeRef, aspectTypeQName);
|
NodeServicePolicies.OnAddAspectPolicy policy = onAddAspectDelegate.get(nodeRef, aspectTypeQName);
|
||||||
policy.onAddAspect(nodeRef, aspectTypeQName);
|
policy.onAddAspect(nodeRef, aspectTypeQName);
|
||||||
}
|
}
|
||||||
@@ -391,6 +487,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
protected void invokeBeforeRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NodeServicePolicies.BeforeRemoveAspectPolicy policy = beforeRemoveAspectDelegate.get(nodeRef, aspectTypeQName);
|
NodeServicePolicies.BeforeRemoveAspectPolicy policy = beforeRemoveAspectDelegate.get(nodeRef, aspectTypeQName);
|
||||||
policy.beforeRemoveAspect(nodeRef, aspectTypeQName);
|
policy.beforeRemoveAspect(nodeRef, aspectTypeQName);
|
||||||
}
|
}
|
||||||
@@ -401,6 +502,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeOnRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
protected void invokeOnRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(nodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NodeServicePolicies.OnRemoveAspectPolicy policy = onRemoveAspectDelegate.get(nodeRef, aspectTypeQName);
|
NodeServicePolicies.OnRemoveAspectPolicy policy = onRemoveAspectDelegate.get(nodeRef, aspectTypeQName);
|
||||||
policy.onRemoveAspect(nodeRef, aspectTypeQName);
|
policy.onRemoveAspect(nodeRef, aspectTypeQName);
|
||||||
}
|
}
|
||||||
@@ -411,6 +517,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeCreateNodeAssociation(NodeRef parentNodeRef, QName assocTypeQName, QName assocQName)
|
protected void invokeBeforeCreateNodeAssociation(NodeRef parentNodeRef, QName assocTypeQName, QName assocQName)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
||||||
// execute policy for node type
|
// execute policy for node type
|
||||||
@@ -425,6 +536,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
{
|
{
|
||||||
// Get the parent reference and the assoc type qName
|
// Get the parent reference and the assoc type qName
|
||||||
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QName assocTypeQName = childAssocRef.getTypeQName();
|
QName assocTypeQName = childAssocRef.getTypeQName();
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
||||||
@@ -439,6 +556,11 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
*/
|
*/
|
||||||
protected void invokeBeforeCreateChildAssociation(NodeRef parentNodeRef, NodeRef childNodeRef, QName assocTypeQName, QName assocQName, boolean isNewNode)
|
protected void invokeBeforeCreateChildAssociation(NodeRef parentNodeRef, NodeRef childNodeRef, QName assocTypeQName, QName assocQName, boolean isNewNode)
|
||||||
{
|
{
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
||||||
// execute policy for node type
|
// execute policy for node type
|
||||||
@@ -453,6 +575,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
{
|
{
|
||||||
// Get the parent reference and the assoc type qName
|
// Get the parent reference and the assoc type qName
|
||||||
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QName assocTypeQName = childAssocRef.getTypeQName();
|
QName assocTypeQName = childAssocRef.getTypeQName();
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
||||||
@@ -467,6 +595,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
protected void invokeBeforeDeleteChildAssociation(ChildAssociationRef childAssocRef)
|
protected void invokeBeforeDeleteChildAssociation(ChildAssociationRef childAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QName assocTypeQName = childAssocRef.getTypeQName();
|
QName assocTypeQName = childAssocRef.getTypeQName();
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
||||||
@@ -481,6 +615,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
protected void invokeOnDeleteChildAssociation(ChildAssociationRef childAssocRef)
|
protected void invokeOnDeleteChildAssociation(ChildAssociationRef childAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
NodeRef parentNodeRef = childAssocRef.getParentRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(parentNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QName assocTypeQName = childAssocRef.getTypeQName();
|
QName assocTypeQName = childAssocRef.getTypeQName();
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(parentNodeRef);
|
||||||
@@ -495,6 +635,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
protected void invokeOnCreateAssociation(AssociationRef nodeAssocRef)
|
protected void invokeOnCreateAssociation(AssociationRef nodeAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef sourceNodeRef = nodeAssocRef.getSourceRef();
|
NodeRef sourceNodeRef = nodeAssocRef.getSourceRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(sourceNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QName assocTypeQName = nodeAssocRef.getTypeQName();
|
QName assocTypeQName = nodeAssocRef.getTypeQName();
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(sourceNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(sourceNodeRef);
|
||||||
@@ -509,6 +655,12 @@ public abstract class AbstractNodeServiceImpl implements NodeService
|
|||||||
protected void invokeOnDeleteAssociation(AssociationRef nodeAssocRef)
|
protected void invokeOnDeleteAssociation(AssociationRef nodeAssocRef)
|
||||||
{
|
{
|
||||||
NodeRef sourceNodeRef = nodeAssocRef.getSourceRef();
|
NodeRef sourceNodeRef = nodeAssocRef.getSourceRef();
|
||||||
|
|
||||||
|
if (ignorePolicy(sourceNodeRef))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QName assocTypeQName = nodeAssocRef.getTypeQName();
|
QName assocTypeQName = nodeAssocRef.getTypeQName();
|
||||||
// get qnames to invoke against
|
// get qnames to invoke against
|
||||||
Set<QName> qnames = getTypeAndAspectQNames(sourceNodeRef);
|
Set<QName> qnames = getTypeAndAspectQNames(sourceNodeRef);
|
||||||
|
@@ -149,6 +149,8 @@ public class MultiTDemoTest extends TestCase
|
|||||||
repoAdminService = (RepoAdminService) ctx.getBean("RepoAdminService");
|
repoAdminService = (RepoAdminService) ctx.getBean("RepoAdminService");
|
||||||
dictionaryService = (DictionaryService) ctx.getBean("DictionaryService");
|
dictionaryService = (DictionaryService) ctx.getBean("DictionaryService");
|
||||||
usageService = (UsageService) ctx.getBean("usageService");
|
usageService = (UsageService) ctx.getBean("usageService");
|
||||||
|
|
||||||
|
createTenants();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -157,6 +159,51 @@ public class MultiTDemoTest extends TestCase
|
|||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createTenants()
|
||||||
|
{
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
createTenant(tenantDomain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateTenants() throws Throwable
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); // authenticate as super-admin
|
||||||
|
|
||||||
|
logger.info("Create tenants");
|
||||||
|
|
||||||
|
Set<NodeRef> personRefs = personService.getAllPeople();
|
||||||
|
//assertEquals(2, personRefs.size()); // super-tenant: admin, guest (note: checking for 2 assumes that this test is run in a fresh bootstrap env)
|
||||||
|
for (NodeRef personRef : personRefs)
|
||||||
|
{
|
||||||
|
String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME);
|
||||||
|
for (final String tenantDomain : tenants)
|
||||||
|
{
|
||||||
|
assertFalse("Unexpected (tenant) user: "+userName, userName.endsWith(tenantDomain));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTenant(final String tenantDomain)
|
||||||
|
{
|
||||||
|
// create tenants (if not already created)
|
||||||
|
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
if (! tenantAdminService.existsTenant(tenantDomain))
|
||||||
|
{
|
||||||
|
//tenantAdminService.createTenant(tenantDomain, DEFAULT_ADMIN_PW.toCharArray(), ROOT_DIR + "/" + tenantDomain);
|
||||||
|
tenantAdminService.createTenant(tenantDomain, (DEFAULT_ADMIN_PW+" "+tenantDomain).toCharArray(), null); // use default root dir
|
||||||
|
|
||||||
|
logger.info("Created tenant " + tenantDomain);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
}
|
||||||
|
|
||||||
public void test_ETHREEOH_2015()
|
public void test_ETHREEOH_2015()
|
||||||
{
|
{
|
||||||
@@ -192,58 +239,6 @@ public class MultiTDemoTest extends TestCase
|
|||||||
usageService.deleteDeltas(personNodeRef);
|
usageService.deleteDeltas(personNodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateTenants() throws Throwable
|
|
||||||
{
|
|
||||||
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); // authenticate as super-admin
|
|
||||||
|
|
||||||
logger.info("Create tenants");
|
|
||||||
|
|
||||||
Set<NodeRef> personRefs = personService.getAllPeople();
|
|
||||||
//assertEquals(2, personRefs.size()); // super-tenant: admin, guest (note: checking for 2 assumes that this test is run in a fresh bootstrap env)
|
|
||||||
for (NodeRef personRef : personRefs)
|
|
||||||
{
|
|
||||||
String userName = (String)nodeService.getProperty(personRef, ContentModel.PROP_USERNAME);
|
|
||||||
for (final String tenantDomain : tenants)
|
|
||||||
{
|
|
||||||
assertFalse("Unexpected (tenant) user: "+userName, userName.endsWith(tenantDomain));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (final String tenantDomain : tenants)
|
|
||||||
{
|
|
||||||
createTenant(tenantDomain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
StringWriter stackTrace = new StringWriter();
|
|
||||||
t.printStackTrace(new PrintWriter(stackTrace));
|
|
||||||
System.err.println(stackTrace.toString());
|
|
||||||
throw t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createTenant(final String tenantDomain)
|
|
||||||
{
|
|
||||||
// create tenants (if not already created)
|
|
||||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
|
||||||
{
|
|
||||||
public Object doWork() throws Exception
|
|
||||||
{
|
|
||||||
if (! tenantAdminService.existsTenant(tenantDomain))
|
|
||||||
{
|
|
||||||
//tenantAdminService.createTenant(tenantDomain, DEFAULT_ADMIN_PW.toCharArray(), ROOT_DIR + "/" + tenantDomain);
|
|
||||||
tenantAdminService.createTenant(tenantDomain, (DEFAULT_ADMIN_PW+" "+tenantDomain).toCharArray(), null); // use default root dir
|
|
||||||
|
|
||||||
logger.info("Created tenant " + tenantDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}, AuthenticationUtil.getSystemUserName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCreateUsers() throws Throwable
|
public void testCreateUsers() throws Throwable
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user