diff --git a/config/alfresco/dao/dao-context.xml b/config/alfresco/dao/dao-context.xml
index ba69f0e48f..78cb98dede 100644
--- a/config/alfresco/dao/dao-context.xml
+++ b/config/alfresco/dao/dao-context.xml
@@ -261,6 +261,7 @@
+
diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/node-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/node-common-SqlMap.xml
index 73db1097e2..1b35589795 100644
--- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/node-common-SqlMap.xml
+++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/node-common-SqlMap.xml
@@ -604,6 +604,19 @@
+
+
select
prop.node_id as node_id,
diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties
index 3445389b2c..1f6d414257 100644
--- a/config/alfresco/version.properties
+++ b/config/alfresco/version.properties
@@ -7,7 +7,7 @@
version.major=4
version.minor=0
version.revision=0
-version.label=a
+version.label=unstable
# Edition label
diff --git a/source/java/org/alfresco/repo/copy/CopyServiceImplTest.java b/source/java/org/alfresco/repo/copy/CopyServiceImplTest.java
index 65eba4d981..bc3d3f1e68 100644
--- a/source/java/org/alfresco/repo/copy/CopyServiceImplTest.java
+++ b/source/java/org/alfresco/repo/copy/CopyServiceImplTest.java
@@ -25,6 +25,10 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import javax.transaction.UserTransaction;
+
+import junit.framework.TestCase;
+
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.evaluator.NoConditionEvaluator;
import org.alfresco.repo.action.executer.AddFeaturesActionExecuter;
@@ -40,8 +44,9 @@ import org.alfresco.repo.dictionary.M2Type;
import org.alfresco.repo.rule.RuleModel;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
-import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.AccessDeniedException;
+import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
+import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionCondition;
import org.alfresco.service.cmr.action.ActionService;
@@ -67,20 +72,26 @@ import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
-import org.alfresco.util.BaseSpringTest;
+import org.alfresco.service.transaction.TransactionService;
+import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.PropertyMap;
+import org.springframework.context.ApplicationContext;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Unit tests for copy service
*
* @author Roy Wetherall
+ * @author Derek Hulley
*/
-public class CopyServiceImplTest extends BaseSpringTest
+public class CopyServiceImplTest extends TestCase
{
- /**
+ private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
+
+ /*
* Services used by the tests
*/
+ private TransactionService transactionService;
private NodeService nodeService;
private NodeService publicNodeService;
private CopyService copyService;
@@ -93,9 +104,10 @@ public class CopyServiceImplTest extends BaseSpringTest
private AuthenticationComponent authenticationComponent;
private MutableAuthenticationService authenticationService;
- /**
+ /*
* Data used by the tests
*/
+ private UserTransaction txn;
private StoreRef storeRef;
private NodeRef sourceNodeRef;
private NodeRef rootNodeRef;
@@ -104,7 +116,7 @@ public class CopyServiceImplTest extends BaseSpringTest
private NodeRef childNodeRef;
private NodeRef destinationNodeRef;
- /**
+ /*
* Types and properties used by the tests
*/
private static final String TEST_TYPE_NAMESPACE = "testTypeNamespaceURI";
@@ -145,52 +157,50 @@ public class CopyServiceImplTest extends BaseSpringTest
*/
private static final String SOME_CONTENT = "This is some content ...";
- /**
- * Sets the meta model DAO
- *
- * @param dictionaryDAO the meta model DAO
- */
- public void setDictionaryDAO(DictionaryDAO dictionaryDAO)
- {
- this.dictionaryDAO = dictionaryDAO;
- }
-
- /**
- * On setup in transaction implementation
- */
@Override
- protected void onSetUpInTransaction()
- throws Exception
+ protected void setUp() throws Exception
{
- // Set the services
- this.nodeService = (NodeService)this.applicationContext.getBean("dbNodeService");
- this.publicNodeService = (NodeService)this.applicationContext.getBean("NodeService");
- this.copyService = (CopyService)this.applicationContext.getBean("copyService");
- this.contentService = (ContentService)this.applicationContext.getBean("contentService");
- this.ruleService = (RuleService)this.applicationContext.getBean("ruleService");
- this.actionService = (ActionService)this.applicationContext.getBean("actionService");
- this.permissionService = (PermissionService)this.applicationContext.getBean("PermissionService");
- this.personService = (PersonService)this.applicationContext.getBean("PersonService");
- this.authenticationComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
- this.authenticationService = (MutableAuthenticationService) this.applicationContext.getBean("authenticationService");
+ if (AlfrescoTransactionSupport.isActualTransactionActive())
+ {
+ fail("Test started with transaction in progress");
+ }
- this.authenticationComponent.setSystemUserAsCurrentUser();
+ ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
+ // Set the services
+ transactionService = serviceRegistry.getTransactionService();
+ nodeService = (NodeService) ctx.getBean("dbNodeService");
+ publicNodeService = serviceRegistry.getNodeService();
+ copyService = (CopyService) ctx.getBean("copyService");
+ contentService = (ContentService) ctx.getBean("contentService");
+ ruleService = (RuleService) ctx.getBean("ruleService");
+ actionService = (ActionService)ctx.getBean("actionService");
+ permissionService = (PermissionService)ctx.getBean("PermissionService");
+ personService = serviceRegistry.getPersonService();
+ authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent");
+ authenticationService = (MutableAuthenticationService) ctx.getBean("authenticationService");
+ dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO");
+
+ authenticationComponent.setSystemUserAsCurrentUser();
+
+ // Ensure that a transaction is present
+ txn = transactionService.getUserTransaction();
+ txn.begin();
// Create the test model
createTestModel();
// Create the store and get the root node reference
- this.storeRef = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
- this.rootNodeRef = this.nodeService.getRootNode(storeRef);
+ storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
+ rootNodeRef = nodeService.getRootNode(storeRef);
// Create the node used for copying
- ChildAssociationRef childAssocRef = this.nodeService.createNode(
+ ChildAssociationRef childAssocRef = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}test"),
TEST_TYPE_QNAME,
createTypePropertyBag());
- this.sourceNodeRef = childAssocRef.getChildRef();
+ sourceNodeRef = childAssocRef.getChildRef();
// Create another bag of properties
Map aspectProperties = new HashMap();
@@ -198,59 +208,59 @@ public class CopyServiceImplTest extends BaseSpringTest
aspectProperties.put(PROP4_QNAME_OPTIONAL, TEST_VALUE_2);
// Apply the test aspect
- this.nodeService.addAspect(
- this.sourceNodeRef,
+ nodeService.addAspect(
+ sourceNodeRef,
TEST_ASPECT_QNAME,
aspectProperties);
- this.nodeService.addAspect(sourceNodeRef, ContentModel.ASPECT_TITLED, null);
+ nodeService.addAspect(sourceNodeRef, ContentModel.ASPECT_TITLED, null);
// Add a child
- ChildAssociationRef temp3 =this.nodeService.createNode(
- this.sourceNodeRef,
+ ChildAssociationRef temp3 =nodeService.createNode(
+ sourceNodeRef,
TEST_CHILD_ASSOC_TYPE_QNAME,
TEST_CHILD_ASSOC_QNAME,
TEST_TYPE_QNAME,
createTypePropertyBag());
- this.childNodeRef = temp3.getChildRef();
+ childNodeRef = temp3.getChildRef();
// Add a child that is primary
- ChildAssociationRef temp2 = this.nodeService.createNode(
+ ChildAssociationRef temp2 = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}testNonPrimaryChild"),
TEST_TYPE_QNAME,
createTypePropertyBag());
- this.nonPrimaryChildNodeRef = temp2.getChildRef();
- this.nodeService.addChild(
- this.sourceNodeRef,
- this.nonPrimaryChildNodeRef,
+ nonPrimaryChildNodeRef = temp2.getChildRef();
+ nodeService.addChild(
+ sourceNodeRef,
+ nonPrimaryChildNodeRef,
TEST_CHILD_ASSOC_TYPE_QNAME,
TEST_CHILD_ASSOC_QNAME2);
// Add a target assoc
- ChildAssociationRef temp = this.nodeService.createNode(
+ ChildAssociationRef temp = nodeService.createNode(
rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}testAssoc"),
TEST_TYPE_QNAME,
createTypePropertyBag());
- this.targetNodeRef = temp.getChildRef();
- this.nodeService.createAssociation(this.sourceNodeRef, this.targetNodeRef, TEST_ASSOC_TYPE_QNAME);
+ targetNodeRef = temp.getChildRef();
+ nodeService.createAssociation(sourceNodeRef, targetNodeRef, TEST_ASSOC_TYPE_QNAME);
// Create a node we can use as the destination in a copy
Map destinationProps = new HashMap();
destinationProps.put(PROP1_QNAME_MANDATORY, TEST_VALUE_1);
destinationProps.put(PROP5_QNAME_MANDATORY, TEST_VALUE_3);
destinationProps.put(ContentModel.PROP_CONTENT, CONTENT_DATA_TEXT);
- ChildAssociationRef temp5 = this.nodeService.createNode(
- this.rootNodeRef,
+ ChildAssociationRef temp5 = nodeService.createNode(
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}testDestinationNode"),
TEST_TYPE_QNAME,
destinationProps);
- this.destinationNodeRef = temp5.getChildRef();
+ destinationNodeRef = temp5.getChildRef();
// Create two users, for use as part of
// the permission related tests
@@ -277,10 +287,13 @@ public class CopyServiceImplTest extends BaseSpringTest
}
@Override
- protected void onTearDownInTransaction() throws Exception
+ protected void tearDown() throws Exception
{
+ if (txn != null)
+ {
+ try { txn.rollback(); } catch (Throwable e) {}
+ }
authenticationComponent.clearCurrentSecurityContext();
- super.onTearDownInTransaction();
}
/**
@@ -370,9 +383,9 @@ public class CopyServiceImplTest extends BaseSpringTest
permissionService.setPermission(rootNodeRef, AuthenticationUtil.getGuestUserName(), PermissionService.CREATE_CHILDREN, true);
assertEquals(3, permissionService.getAllSetPermissions(sourceNodeRef).size());
- NodeRef copy = this.copyService.copy(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copy = copyService.copy(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}aclCopyOne"));
@@ -380,7 +393,7 @@ public class CopyServiceImplTest extends BaseSpringTest
// Admin
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
copy = copyService.copy(
sourceNodeRef,
@@ -392,7 +405,7 @@ public class CopyServiceImplTest extends BaseSpringTest
// guest
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
copy = copyService.copy(
sourceNodeRef,
@@ -403,9 +416,9 @@ public class CopyServiceImplTest extends BaseSpringTest
// guest with read permissions - write from ownership
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
permissionService.setPermission(sourceNodeRef, AuthenticationUtil.getGuestUserName(), PermissionService.READ_PERMISSIONS, true);
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
copy = copyService.copy(
sourceNodeRef,
@@ -417,9 +430,9 @@ public class CopyServiceImplTest extends BaseSpringTest
// guest with read and write
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
permissionService.setPermission(rootNodeRef, AuthenticationUtil.getGuestUserName(), PermissionService.CHANGE_PERMISSIONS, true);
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
copy = copyService.copy(
sourceNodeRef,
@@ -431,9 +444,9 @@ public class CopyServiceImplTest extends BaseSpringTest
// guest with write but not read
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
permissionService.setPermission(sourceNodeRef, AuthenticationUtil.getGuestUserName(), PermissionService.READ_PERMISSIONS, false);
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
copy = copyService.copy(
sourceNodeRef,
@@ -443,9 +456,9 @@ public class CopyServiceImplTest extends BaseSpringTest
assertEquals(3, permissionService.getAllSetPermissions(copy).size());
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getAdminUserName());
permissionService.deletePermission(sourceNodeRef, AuthenticationUtil.getGuestUserName(), PermissionService.READ_PERMISSIONS);
- this.authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
+ authenticationComponent.setCurrentUser(AuthenticationUtil.getGuestUserName());
copy = copyService.copy(
sourceNodeRef,
@@ -466,37 +479,37 @@ public class CopyServiceImplTest extends BaseSpringTest
public void testCopyToNewNode()
{
// Check that the node has no copies
- List copies = this.copyService.getCopies(this.sourceNodeRef);
+ List copies = copyService.getCopies(sourceNodeRef);
assertNotNull(copies);
assertTrue(copies.isEmpty());
// Copy to new node without copying children
- NodeRef copy = this.copyService.copy(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copy = copyService.copy(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}copyAssoc"));
- checkCopiedNode(this.sourceNodeRef, copy, true, true, false);
- List copies2 = this.copyService.getCopies(this.sourceNodeRef);
+ checkCopiedNode(sourceNodeRef, copy, true, true, false);
+ List copies2 = copyService.getCopies(sourceNodeRef);
assertNotNull(copies2);
assertEquals(1, copies2.size());
// Copy to new node, copying children
- NodeRef copy2 = this.copyService.copy(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copy2 = copyService.copy(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}copyAssoc2"),
true);
- checkCopiedNode(this.sourceNodeRef, copy2, true, true, true);
- List copies3 = this.copyService.getCopies(this.sourceNodeRef);
+ checkCopiedNode(sourceNodeRef, copy2, true, true, true);
+ List copies3 = copyService.getCopies(sourceNodeRef);
assertNotNull(copies3);
assertEquals(2, copies3.size());
// Check that a copy of a copy works correctly
- NodeRef copyOfCopy = this.copyService.copy(
+ NodeRef copyOfCopy = copyService.copy(
copy,
- this.rootNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}copyOfCopy"));
checkCopiedNode(copy, copyOfCopy, true, true, false);
@@ -505,22 +518,22 @@ public class CopyServiceImplTest extends BaseSpringTest
// TODO check copying from a lockable copy
// Check copying from a node with content
- ContentWriter contentWriter = this.contentService.getWriter(this.sourceNodeRef, ContentModel.PROP_CONTENT, true);
+ ContentWriter contentWriter = contentService.getWriter(sourceNodeRef, ContentModel.PROP_CONTENT, true);
contentWriter.putContent(SOME_CONTENT);
- NodeRef copyWithContent = this.copyService.copy(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copyWithContent = copyService.copy(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}copyWithContent"));
- checkCopiedNode(this.sourceNodeRef, copyWithContent, true, true, false);
- ContentReader contentReader = this.contentService.getReader(copyWithContent, ContentModel.PROP_CONTENT);
+ checkCopiedNode(sourceNodeRef, copyWithContent, true, true, false);
+ ContentReader contentReader = contentService.getReader(copyWithContent, ContentModel.PROP_CONTENT);
assertNotNull(contentReader);
assertEquals(SOME_CONTENT, contentReader.getContentString());
// TODO check copying to a different store
//System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
}
public void testCopyNodeWithRules()
@@ -531,38 +544,38 @@ public class CopyServiceImplTest extends BaseSpringTest
Map props = new HashMap(1);
props.put(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
- Action action = this.actionService.createAction(AddFeaturesActionExecuter.NAME, props);
+ Action action = actionService.createAction(AddFeaturesActionExecuter.NAME, props);
rule.setAction(action);
- ActionCondition actionCondition = this.actionService.createActionCondition(NoConditionEvaluator.NAME);
+ ActionCondition actionCondition = actionService.createActionCondition(NoConditionEvaluator.NAME);
action.addActionCondition(actionCondition);
- this.ruleService.saveRule(this.sourceNodeRef, rule);
+ ruleService.saveRule(sourceNodeRef, rule);
assertNotNull(rule.getNodeRef());
- assertEquals(this.sourceNodeRef, this.ruleService.getOwningNodeRef(rule));
+ assertEquals(sourceNodeRef, ruleService.getOwningNodeRef(rule));
//System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
//System.out.println(" ------------------------------ ");
// Now copy the node that has rules associated with it
- NodeRef copy = this.copyService.copy(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copy = copyService.copy(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}withRulesCopy"),
true);
//System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
- checkCopiedNode(this.sourceNodeRef, copy, true, true, true);
+ checkCopiedNode(sourceNodeRef, copy, true, true, true);
- assertTrue(this.nodeService.hasAspect(copy, RuleModel.ASPECT_RULES));
- assertTrue(this.ruleService.hasRules(copy));
- assertTrue(this.ruleService.rulesEnabled(copy));
+ assertTrue(nodeService.hasAspect(copy, RuleModel.ASPECT_RULES));
+ assertTrue(ruleService.hasRules(copy));
+ assertTrue(ruleService.rulesEnabled(copy));
- List copiedRules = this.ruleService.getRules(copy);
+ List copiedRules = ruleService.getRules(copy);
assertEquals(1, copiedRules.size());
Rule copiedRule = copiedRules.get(0);
@@ -570,44 +583,44 @@ public class CopyServiceImplTest extends BaseSpringTest
assertFalse(copiedRule.getNodeRef().equals(rule.getNodeRef()));
assertEquals(rule.getTitle(), copiedRule.getTitle());
assertEquals(rule.getDescription(), copiedRule.getDescription());
- assertEquals(copy, this.ruleService.getOwningNodeRef(copiedRule));
+ assertEquals(copy, ruleService.getOwningNodeRef(copiedRule));
assertEquals(rule.getAction().getActionDefinitionName(), copiedRule.getAction().getActionDefinitionName());
// Now copy the node without copying the children and check that the rules have been copied
- NodeRef copy2 = this.copyService.copy(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copy2 = copyService.copy(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}withRuleCopyNoChildren"),
false);
// System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
- checkCopiedNode(this.sourceNodeRef, copy2, true, true, false);
+ checkCopiedNode(sourceNodeRef, copy2, true, true, false);
- //assertTrue(this.configurableService.isConfigurable(copy2));
- //assertNotNull(this.configurableService.getConfigurationFolder(copy2));
- //assertFalse(this.configurableService.getConfigurationFolder(this.sourceNodeRef) == this.configurableService.getConfigurationFolder(copy2));
+ //assertTrue(configurableService.isConfigurable(copy2));
+ //assertNotNull(configurableService.getConfigurationFolder(copy2));
+ //assertFalse(configurableService.getConfigurationFolder(sourceNodeRef) == configurableService.getConfigurationFolder(copy2));
- assertTrue(this.nodeService.hasAspect(copy2, RuleModel.ASPECT_RULES));
- assertTrue(this.ruleService.hasRules(copy2));
- assertTrue(this.ruleService.rulesEnabled(copy2));
- List copiedRules2 = this.ruleService.getRules(copy2);
+ assertTrue(nodeService.hasAspect(copy2, RuleModel.ASPECT_RULES));
+ assertTrue(ruleService.hasRules(copy2));
+ assertTrue(ruleService.rulesEnabled(copy2));
+ List copiedRules2 = ruleService.getRules(copy2);
assertEquals(1, copiedRules.size());
Rule copiedRule2 = copiedRules2.get(0);
assertFalse(rule.getNodeRef().equals(copiedRule2.getNodeRef()));
assertEquals(rule.getTitle(), copiedRule2.getTitle());
assertEquals(rule.getDescription(), copiedRule2.getDescription());
- assertEquals(this.ruleService.getOwningNodeRef(copiedRule2), copy2);
+ assertEquals(ruleService.getOwningNodeRef(copiedRule2), copy2);
assertEquals(rule.getAction().getActionDefinitionName(), copiedRule2.getAction().getActionDefinitionName());
}
public void testCopyToExistingNode()
{
// Copy nodes within the same store
- this.copyService.copy(this.sourceNodeRef, this.destinationNodeRef);
- checkCopiedNode(this.sourceNodeRef, this.destinationNodeRef, false, true, true);
+ copyService.copy(sourceNodeRef, destinationNodeRef);
+ checkCopiedNode(sourceNodeRef, destinationNodeRef, false, true, true);
// TODO check copying from a copy
// TODO check copying from a versioned copy
@@ -617,7 +630,7 @@ public class CopyServiceImplTest extends BaseSpringTest
// TODO check copying nodes between stores
//System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
}
/**
@@ -628,21 +641,21 @@ public class CopyServiceImplTest extends BaseSpringTest
PropertyMap props = new PropertyMap();
// Need to create a potentially recursive node structure
props.put(ContentModel.PROP_NODE_UUID, "nodeOne");
- NodeRef nodeOne = this.nodeService.createNode(
- this.rootNodeRef,
+ NodeRef nodeOne = nodeService.createNode(
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_CONTAINER,
props).getChildRef();
props.put(ContentModel.PROP_NODE_UUID, "nodeTwo");
- NodeRef nodeTwo = this.nodeService.createNode(
+ NodeRef nodeTwo = nodeService.createNode(
nodeOne,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
ContentModel.TYPE_CONTAINER,
props).getChildRef();
props.put(ContentModel.PROP_NODE_UUID, "nodeThree");
- NodeRef nodeThree = this.nodeService.createNode(
+ NodeRef nodeThree = nodeService.createNode(
nodeTwo,
ContentModel.ASSOC_CHILDREN,
ContentModel.ASSOC_CHILDREN,
@@ -650,23 +663,23 @@ public class CopyServiceImplTest extends BaseSpringTest
props).getChildRef();
// Issue a potentialy recursive copy
- this.copyService.copy(nodeOne, nodeThree, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, true);
+ copyService.copy(nodeOne, nodeThree, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, true);
//System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
}
public void testCopyResidualProperties() throws Exception
{
QName nodeOneAssocName = QName.createQName("{test}nodeOne");
- NodeRef nodeOne = this.nodeService.createNode(
- this.rootNodeRef,
+ NodeRef nodeOne = nodeService.createNode(
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
nodeOneAssocName,
TEST_TYPE_QNAME).getChildRef();
- this.nodeService.setProperty(nodeOne, PROP_QNAME_RESIDUAL_NODE_REF, nodeOne);
- this.nodeService.setProperty(nodeOne, PROP_QNAME_RESIDUAL_ANY, nodeOne);
+ nodeService.setProperty(nodeOne, PROP_QNAME_RESIDUAL_NODE_REF, nodeOne);
+ nodeService.setProperty(nodeOne, PROP_QNAME_RESIDUAL_ANY, nodeOne);
NodeRef nodeOneCopy = copyService.copy(
nodeOne,
rootNodeRef,
@@ -692,56 +705,56 @@ public class CopyServiceImplTest extends BaseSpringTest
QName nodeThreeAssocName = QName.createQName("{test}nodeThree");
QName nodeFourAssocName = QName.createQName("{test}nodeFour");
- NodeRef nodeNotCopied = this.nodeService.createNode(
- this.rootNodeRef,
+ NodeRef nodeNotCopied = nodeService.createNode(
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
nodeOneAssocName,
TEST_TYPE_QNAME).getChildRef();
- NodeRef nodeOne = this.nodeService.createNode(
- this.rootNodeRef,
+ NodeRef nodeOne = nodeService.createNode(
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
nodeOneAssocName,
TEST_TYPE_QNAME).getChildRef();
- NodeRef nodeTwo = this.nodeService.createNode(
+ NodeRef nodeTwo = nodeService.createNode(
nodeOne,
TEST_CHILD_ASSOC_TYPE_QNAME,
nodeTwoAssocName,
TEST_TYPE_QNAME).getChildRef();
- NodeRef nodeThree = this.nodeService.createNode(
+ NodeRef nodeThree = nodeService.createNode(
nodeTwo,
TEST_CHILD_ASSOC_TYPE_QNAME,
nodeThreeAssocName,
TEST_TYPE_QNAME).getChildRef();
- NodeRef nodeFour = this.nodeService.createNode(
+ NodeRef nodeFour = nodeService.createNode(
nodeOne,
TEST_CHILD_ASSOC_TYPE_QNAME,
nodeFourAssocName,
TEST_TYPE_QNAME).getChildRef();
- this.nodeService.addChild(nodeFour, nodeThree, TEST_CHILD_ASSOC_TYPE_QNAME, TEST_CHILD_ASSOC_QNAME);
- this.nodeService.createAssociation(nodeTwo, nodeThree, TEST_ASSOC_TYPE_QNAME);
- this.nodeService.createAssociation(nodeTwo, nodeNotCopied, TEST_ASSOC_TYPE_QNAME);
+ nodeService.addChild(nodeFour, nodeThree, TEST_CHILD_ASSOC_TYPE_QNAME, TEST_CHILD_ASSOC_QNAME);
+ nodeService.createAssociation(nodeTwo, nodeThree, TEST_ASSOC_TYPE_QNAME);
+ nodeService.createAssociation(nodeTwo, nodeNotCopied, TEST_ASSOC_TYPE_QNAME);
// Make node one actionable with a rule to copy nodes into node two
Map params = new HashMap(1);
params.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, nodeTwo);
Rule rule = new Rule();
rule.setRuleType(RuleType.INBOUND);
- Action action = this.actionService.createAction(CopyActionExecuter.NAME, params);
- ActionCondition condition = this.actionService.createActionCondition(NoConditionEvaluator.NAME);
+ Action action = actionService.createAction(CopyActionExecuter.NAME, params);
+ ActionCondition condition = actionService.createActionCondition(NoConditionEvaluator.NAME);
action.addActionCondition(condition);
rule.setAction(action);
- this.ruleService.saveRule(nodeOne, rule);
+ ruleService.saveRule(nodeOne, rule);
// Do a deep copy
- NodeRef nodeOneCopy = this.copyService.copy(nodeOne, this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}copiedNodeOne"), true);
+ NodeRef nodeOneCopy = copyService.copy(nodeOne, rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}copiedNodeOne"), true);
NodeRef nodeTwoCopy = null;
NodeRef nodeThreeCopy = null;
NodeRef nodeFourCopy = null;
//System.out.println(
- // NodeStoreInspector.dumpNodeStore(this.nodeService, this.storeRef));
+ // NodeStoreInspector.dumpNodeStore(nodeService, storeRef));
- List nodeOneCopyChildren = this.nodeService.getChildAssocs(nodeOneCopy);
+ List nodeOneCopyChildren = nodeService.getChildAssocs(nodeOneCopy);
assertNotNull(nodeOneCopyChildren);
assertEquals(3, nodeOneCopyChildren.size());
for (ChildAssociationRef nodeOneCopyChild : nodeOneCopyChildren)
@@ -750,7 +763,7 @@ public class CopyServiceImplTest extends BaseSpringTest
{
nodeTwoCopy = nodeOneCopyChild.getChildRef();
- List nodeTwoCopyChildren = this.nodeService.getChildAssocs(nodeTwoCopy);
+ List nodeTwoCopyChildren = nodeService.getChildAssocs(nodeTwoCopy);
assertNotNull(nodeTwoCopyChildren);
assertEquals(1, nodeTwoCopyChildren.size());
for (ChildAssociationRef nodeTwoCopyChild : nodeTwoCopyChildren)
@@ -771,7 +784,7 @@ public class CopyServiceImplTest extends BaseSpringTest
assertNotNull(nodeFourCopy);
// Check the non primary child assoc
- List children = this.nodeService.getChildAssocs(
+ List children = nodeService.getChildAssocs(
nodeFourCopy,
RegexQNamePattern.MATCH_ALL,
TEST_CHILD_ASSOC_QNAME);
@@ -781,7 +794,7 @@ public class CopyServiceImplTest extends BaseSpringTest
assertEquals(child.getChildRef(), nodeThree);
// Check the target assoc
- List assocs = this.nodeService.getTargetAssocs(nodeTwoCopy, TEST_ASSOC_TYPE_QNAME);
+ List assocs = nodeService.getTargetAssocs(nodeTwoCopy, TEST_ASSOC_TYPE_QNAME);
assertNotNull(assocs);
assertEquals(2, assocs.size());
AssociationRef assoc0 = assocs.get(0);
@@ -790,7 +803,7 @@ public class CopyServiceImplTest extends BaseSpringTest
assertTrue(assoc1.getTargetRef().equals(nodeThreeCopy) || assoc1.getTargetRef().equals(nodeNotCopied));
// Check that the rule parameter values have been made relative
- List rules = this.ruleService.getRules(nodeOneCopy);
+ List rules = ruleService.getRules(nodeOneCopy);
assertNotNull(rules);
assertEquals(1, rules.size());
Rule copiedRule = rules.get(0);
@@ -805,26 +818,26 @@ public class CopyServiceImplTest extends BaseSpringTest
public void testCopyAndRename()
{
// Check a normal copy with no dup restrictions
- NodeRef copy = this.copyService.copyAndRename(
- this.sourceNodeRef,
- this.rootNodeRef,
+ NodeRef copy = copyService.copyAndRename(
+ sourceNodeRef,
+ rootNodeRef,
ContentModel.ASSOC_CHILDREN,
QName.createQName("{test}copyAssoc"),
false);
- checkCopiedNode(this.sourceNodeRef, copy, true, true, false);
- assertTrue(TEST_NAME.equals(this.nodeService.getProperty(copy, ContentModel.PROP_NAME)));
+ checkCopiedNode(sourceNodeRef, copy, true, true, false);
+ assertTrue(TEST_NAME.equals(nodeService.getProperty(copy, ContentModel.PROP_NAME)));
// Create a folder and content node
Map propsFolder = new HashMap(1);
propsFolder.put(ContentModel.PROP_NAME, "tempFolder");
- NodeRef folderNode = this.nodeService.createNode(this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}tempFolder"), ContentModel.TYPE_FOLDER, propsFolder).getChildRef();
+ NodeRef folderNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}tempFolder"), ContentModel.TYPE_FOLDER, propsFolder).getChildRef();
Map props = new HashMap(1);
props.put(ContentModel.PROP_NAME, TEST_NAME);
- NodeRef contentNode = this.nodeService.createNode(folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}renametest"), ContentModel.TYPE_CONTENT, props).getChildRef();
+ NodeRef contentNode = nodeService.createNode(folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}renametest"), ContentModel.TYPE_CONTENT, props).getChildRef();
// Now copy the content node with the duplicate name restriction
- NodeRef contentCopy = this.copyService.copy(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}bobbins"), false);
- assertFalse(TEST_NAME.equals(this.nodeService.getProperty(contentCopy, ContentModel.PROP_NAME)));
+ NodeRef contentCopy = copyService.copy(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName("{test}bobbins"), false);
+ assertFalse(TEST_NAME.equals(nodeService.getProperty(contentCopy, ContentModel.PROP_NAME)));
}
/**
@@ -835,25 +848,25 @@ public class CopyServiceImplTest extends BaseSpringTest
// Create a folder and content node
Map propsFolder = new HashMap(1);
propsFolder.put(ContentModel.PROP_NAME, "tempFolder");
- NodeRef folderNode = this.nodeService.createNode(this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "tempFolder"), ContentModel.TYPE_FOLDER, propsFolder).getChildRef();
+ NodeRef folderNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "tempFolder"), ContentModel.TYPE_FOLDER, propsFolder).getChildRef();
Map props = new HashMap(1);
props.put(ContentModel.PROP_NAME, "myDoc.txt");
- NodeRef contentNode = this.nodeService.createNode(folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myDoc.txt"), ContentModel.TYPE_CONTENT, props).getChildRef();
+ NodeRef contentNode = nodeService.createNode(folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myDoc.txt"), ContentModel.TYPE_CONTENT, props).getChildRef();
- NodeRef copy = this.copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
- assertEquals("Copy of myDoc.txt", this.nodeService.getProperty(copy, ContentModel.PROP_NAME));
+ NodeRef copy = copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
+ assertEquals("Copy of myDoc.txt", nodeService.getProperty(copy, ContentModel.PROP_NAME));
QName copyQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Copy of myDoc.txt");
- assertEquals(copyQName, this.nodeService.getPrimaryParent(copy).getQName());
+ assertEquals(copyQName, nodeService.getPrimaryParent(copy).getQName());
- copy = this.copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
- assertEquals("Copy of Copy of myDoc.txt", this.nodeService.getProperty(copy, ContentModel.PROP_NAME));
+ copy = copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
+ assertEquals("Copy of Copy of myDoc.txt", nodeService.getProperty(copy, ContentModel.PROP_NAME));
copyQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Copy of Copy of myDoc.txt");
- assertEquals(copyQName, this.nodeService.getPrimaryParent(copy).getQName());
+ assertEquals(copyQName, nodeService.getPrimaryParent(copy).getQName());
- copy = this.copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
- assertEquals("Copy of Copy of Copy of myDoc.txt", this.nodeService.getProperty(copy, ContentModel.PROP_NAME));
+ copy = copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
+ assertEquals("Copy of Copy of Copy of myDoc.txt", nodeService.getProperty(copy, ContentModel.PROP_NAME));
copyQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Copy of Copy of Copy of myDoc.txt");
- assertEquals(copyQName, this.nodeService.getPrimaryParent(copy).getQName());
+ assertEquals(copyQName, nodeService.getPrimaryParent(copy).getQName());
}
@@ -867,7 +880,7 @@ public class CopyServiceImplTest extends BaseSpringTest
// Create a folder and content node
Map propsFolder = new HashMap(1);
propsFolder.put(ContentModel.PROP_NAME, "tempFolder");
- NodeRef folderNode = this.nodeService.createNode(this.rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "tempFolder"), ContentModel.TYPE_FOLDER, propsFolder).getChildRef();
+ NodeRef folderNode = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "tempFolder"), ContentModel.TYPE_FOLDER, propsFolder).getChildRef();
Map props = new HashMap(1);
props.put(ContentModel.PROP_NAME, "myDoc.txt");
@@ -883,12 +896,12 @@ public class CopyServiceImplTest extends BaseSpringTest
description.addValue(Locale.ITALY, ITALY_DESCRIPTION);
props.put(ContentModel.PROP_DESCRIPTION, description);
- NodeRef contentNode = this.nodeService.createNode(folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myDoc.txt"), ContentModel.TYPE_CONTENT, props).getChildRef();
+ NodeRef contentNode = nodeService.createNode(folderNode, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myDoc.txt"), ContentModel.TYPE_CONTENT, props).getChildRef();
- NodeRef copy = this.copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
- assertEquals("Copy of myDoc.txt", this.nodeService.getProperty(copy, ContentModel.PROP_NAME));
+ NodeRef copy = copyService.copyAndRename(contentNode, folderNode, ContentModel.ASSOC_CONTAINS, null, false);
+ assertEquals("Copy of myDoc.txt", nodeService.getProperty(copy, ContentModel.PROP_NAME));
QName copyQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "Copy of myDoc.txt");
- assertEquals(copyQName, this.nodeService.getPrimaryParent(copy).getQName());
+ assertEquals(copyQName, nodeService.getPrimaryParent(copy).getQName());
// Test uses DB Node Service.
Serializable desc = nodeService.getProperty(copy, ContentModel.PROP_DESCRIPTION);
@@ -937,7 +950,7 @@ public class CopyServiceImplTest extends BaseSpringTest
} catch(AccessDeniedException e) {}
// Allow the read, but the destination won't accept it
- this.authenticationComponent.setSystemUserAsCurrentUser();
+ authenticationComponent.setSystemUserAsCurrentUser();
permissionService.setPermission(sourceNodeRef, USER_2, PermissionService.CONTRIBUTOR, true);
permissionService.setPermission(targetNodeRef, USER_2, PermissionService.CONTRIBUTOR, false);
AuthenticationUtil.setFullyAuthenticatedUser(USER_2);
@@ -948,7 +961,7 @@ public class CopyServiceImplTest extends BaseSpringTest
// Now allow on the destination, should go through
- this.authenticationComponent.setSystemUserAsCurrentUser();
+ authenticationComponent.setSystemUserAsCurrentUser();
permissionService.setPermission(targetNodeRef, USER_2, PermissionService.CONTRIBUTOR, true);
AuthenticationUtil.setFullyAuthenticatedUser(USER_2);
@@ -1053,9 +1066,9 @@ public class CopyServiceImplTest extends BaseSpringTest
if (sameStore == true)
{
// Check that the copy aspect has been applied to the copy
- boolean hasCopyAspect = this.nodeService.hasAspect(destinationNodeRef, ContentModel.ASPECT_COPIEDFROM);
+ boolean hasCopyAspect = nodeService.hasAspect(destinationNodeRef, ContentModel.ASPECT_COPIEDFROM);
assertTrue("Missing aspect: " + ContentModel.ASPECT_COPIEDFROM, hasCopyAspect);
- NodeRef copyNodeRef = (NodeRef)this.nodeService.getProperty(destinationNodeRef, ContentModel.PROP_COPY_REFERENCE);
+ NodeRef copyNodeRef = (NodeRef)nodeService.getProperty(destinationNodeRef, ContentModel.PROP_COPY_REFERENCE);
assertNotNull(copyNodeRef);
assertEquals(sourceNodeRef, copyNodeRef);
}
@@ -1066,11 +1079,11 @@ public class CopyServiceImplTest extends BaseSpringTest
}
}
- boolean hasTestAspect = this.nodeService.hasAspect(destinationNodeRef, TEST_ASPECT_QNAME);
+ boolean hasTestAspect = nodeService.hasAspect(destinationNodeRef, TEST_ASPECT_QNAME);
assertTrue(hasTestAspect);
// Check that all the correct properties have been copied
- Map destinationProperties = this.nodeService.getProperties(destinationNodeRef);
+ Map destinationProperties = nodeService.getProperties(destinationNodeRef);
assertNotNull(destinationProperties);
String value1 = (String)destinationProperties.get(PROP1_QNAME_MANDATORY);
assertNotNull(value1);
@@ -1086,18 +1099,18 @@ public class CopyServiceImplTest extends BaseSpringTest
assertEquals(TEST_VALUE_2, value4);
// Check all the target associations have been copied
- List destinationTargets = this.nodeService.getTargetAssocs(destinationNodeRef, TEST_ASSOC_TYPE_QNAME);
+ List destinationTargets = nodeService.getTargetAssocs(destinationNodeRef, TEST_ASSOC_TYPE_QNAME);
assertNotNull(destinationTargets);
assertEquals(1, destinationTargets.size());
AssociationRef nodeAssocRef = destinationTargets.get(0);
assertNotNull(nodeAssocRef);
- assertEquals(this.targetNodeRef, nodeAssocRef.getTargetRef());
+ assertEquals(targetNodeRef, nodeAssocRef.getTargetRef());
// Check all the child associations have been copied
- List childAssocRefs = this.nodeService.getChildAssocs(destinationNodeRef);
+ List childAssocRefs = nodeService.getChildAssocs(destinationNodeRef);
assertNotNull(childAssocRefs);
int expectedSize = copyChildren ? 2 : 0;
- if (this.nodeService.hasAspect(destinationNodeRef, RuleModel.ASPECT_RULES) == true)
+ if (nodeService.hasAspect(destinationNodeRef, RuleModel.ASPECT_RULES) == true)
{
expectedSize = expectedSize + 1;
}
@@ -1109,7 +1122,7 @@ public class CopyServiceImplTest extends BaseSpringTest
{
// Since this child is non-primary in the source it will always be non-primary in the destination
assertFalse(ref.isPrimary());
- assertEquals(this.nonPrimaryChildNodeRef, ref.getChildRef());
+ assertEquals(nonPrimaryChildNodeRef, ref.getChildRef());
}
else
{
@@ -1118,18 +1131,18 @@ public class CopyServiceImplTest extends BaseSpringTest
if (ref.getTypeQName().equals(RuleModel.ASSOC_RULE_FOLDER) == true)
{
assertTrue(ref.isPrimary());
- assertTrue(this.childNodeRef.equals(ref.getChildRef()) == false);
+ assertTrue(childNodeRef.equals(ref.getChildRef()) == false);
}
else
{
assertFalse(ref.isPrimary());
- assertEquals(this.childNodeRef, ref.getChildRef());
+ assertEquals(childNodeRef, ref.getChildRef());
}
}
else
{
assertTrue(ref.isPrimary());
- assertTrue(this.childNodeRef.equals(ref.getChildRef()) == false);
+ assertTrue(childNodeRef.equals(ref.getChildRef()) == false);
// TODO need to check that the copied child has all the correct details ..
}
diff --git a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java
index 7d512d1d99..18e3d6931a 100644
--- a/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/node/AbstractNodeDAOImpl.java
@@ -3146,7 +3146,70 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
/*
* Bulk caching
*/
-
+
+ // TODO there must be a way to limit the repeated code here and in cacheNodes(List)
+ public void cacheNodesById(List nodeIds)
+ {
+ /*
+ * ALF-2712: Performance degradation from 3.1.0 to 3.1.2
+ * ALF-2784: Degradation of performance between 3.1.1 and 3.2x (observed in JSF)
+ *
+ * There is an obvious cost associated with querying the database to pull back nodes,
+ * and there is additional cost associated with putting the resultant entries into the
+ * caches. It is NO MORE expensive to check the cache than it is to put an entry into it
+ * - and probably cheaper considering cache replication - so we start checking nodes to see
+ * if they have entries before passing them over for batch loading.
+ *
+ * However, when running against a cold cache or doing a first-time query against some
+ * part of the repo, we will be checking for entries in the cache and consistently getting
+ * no results. To avoid unnecessary checking when the cache is PROBABLY cold, we
+ * examine the ratio of hits/misses at regular intervals.
+ */
+ if (nodeIds.size() < 10)
+ {
+ // We only cache where the number of results is potentially
+ // a problem for the N+1 loading that might result.
+ return;
+ }
+
+ int foundCacheEntryCount = 0;
+ int missingCacheEntryCount = 0;
+ boolean forceBatch = false;
+
+ List batchLoadNodeIds = new ArrayList(nodeIds.size());
+ for (Long nodeId : nodeIds)
+ {
+ if (!forceBatch)
+ {
+ // Is this node in the cache?
+ if (nodesCache.getValue(nodeId) != null)
+ {
+ foundCacheEntryCount++; // Don't add it to the batch
+ continue;
+ }
+ else
+ {
+ missingCacheEntryCount++; // Fall through and add it to the batch
+ }
+ if (foundCacheEntryCount + missingCacheEntryCount % 100 == 0)
+ {
+ // We force the batch if the number of hits drops below the number of misses
+ forceBatch = foundCacheEntryCount < missingCacheEntryCount;
+ }
+ }
+
+ batchLoadNodeIds.add(nodeId);
+ }
+
+ int size = batchLoadNodeIds.size();
+ cacheNodesBatch(batchLoadNodeIds);
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Pre-loaded " + size + " nodes.");
+ }
+ }
+
/**
* {@inheritDoc}
*
@@ -3242,27 +3305,47 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
if (batch.size() >= batchSize)
{
// Preload
- cacheNodesNoBatch(storeId, batch);
+ cacheNodesNoBatch(selectNodesByUuids(storeId, batch));
batch.clear();
}
}
// Load any remaining nodes
if (batch.size() > 0)
{
- cacheNodesNoBatch(storeId, batch);
+ cacheNodesNoBatch(selectNodesByUuids(storeId, batch));
+ }
+ }
+
+ private void cacheNodesBatch(List nodeIds)
+ {
+ int batchSize = 256;
+ SortedSet batch = new TreeSet();
+ for (Long nodeId : nodeIds)
+ {
+ batch.add(nodeId);
+ if (batch.size() >= batchSize)
+ {
+ // Preload
+ cacheNodesNoBatch(selectNodesByIds(batch));
+ batch.clear();
+ }
+ }
+ // Load any remaining nodes
+ if (batch.size() > 0)
+ {
+ cacheNodesNoBatch(selectNodesByIds(batch));
}
}
/**
* Bulk-fetch the nodes for a given store. All nodes passed in are fetched.
*/
- private void cacheNodesNoBatch(Long storeId, SortedSet uuids)
+ private void cacheNodesNoBatch(List nodes)
{
// Get the nodes
- List nodes = selectNodesByUuids(storeId, uuids);
SortedSet aspectNodeIds = new TreeSet();
SortedSet propertiesNodeIds = new TreeSet();
- for (NodeEntity node : nodes)
+ for (Node node : nodes)
{
Long nodeId = node.getId();
nodesCache.setValue(nodeId, node);
@@ -3276,6 +3359,12 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
}
}
+ if(logger.isDebugEnabled())
+ {
+ logger.debug("Pre-loaded " + propertiesNodeIds.size() + " properties");
+ logger.debug("Pre-loaded " + propertiesNodeIds.size() + " aspects");
+ }
+
List nodeAspects = selectNodeAspects(aspectNodeIds);
for (NodeAspectsEntity nodeAspect : nodeAspects)
{
@@ -3450,7 +3539,8 @@ public abstract class AbstractNodeDAOImpl implements NodeDAO, BatchingDAO
protected abstract int deleteNodesByCommitTime(boolean deletedOnly, long maxTxnCommitTimeMs);
protected abstract NodeEntity selectNodeById(Long id, Boolean deleted);
protected abstract NodeEntity selectNodeByNodeRef(NodeRef nodeRef, Boolean deleted);
- protected abstract List selectNodesByUuids(Long storeId, SortedSet uuids);
+ protected abstract List selectNodesByUuids(Long storeId, SortedSet uuids);
+ protected abstract List selectNodesByIds(SortedSet ids);
protected abstract Map> selectNodeProperties(Set nodeIds);
protected abstract List selectNodeAspects(Set nodeIds);
protected abstract Map selectNodeProperties(Long nodeId);
diff --git a/source/java/org/alfresco/repo/domain/node/ibatis/NodeBatchLoadEntity.java b/source/java/org/alfresco/repo/domain/node/ibatis/NodeBatchLoadEntity.java
index 33f500c30e..7c21d82744 100644
--- a/source/java/org/alfresco/repo/domain/node/ibatis/NodeBatchLoadEntity.java
+++ b/source/java/org/alfresco/repo/domain/node/ibatis/NodeBatchLoadEntity.java
@@ -30,6 +30,7 @@ public class NodeBatchLoadEntity
{
private Long storeId;
private List uuids;
+ private List ids;
public Long getStoreId()
{
@@ -47,5 +48,12 @@ public class NodeBatchLoadEntity
{
this.uuids = uuids;
}
-
+ public List getIds()
+ {
+ return ids;
+ }
+ public void setIds(List ids)
+ {
+ this.ids = ids;
+ }
}
diff --git a/source/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java b/source/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java
index 9017b5d751..a03be2f531 100644
--- a/source/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/node/ibatis/NodeDAOImpl.java
@@ -31,6 +31,7 @@ import java.util.SortedSet;
import org.alfresco.repo.domain.node.AbstractNodeDAOImpl;
import org.alfresco.repo.domain.node.ChildAssocEntity;
import org.alfresco.repo.domain.node.ChildPropertyEntity;
+import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.node.NodeAspectsEntity;
import org.alfresco.repo.domain.node.NodeAssocEntity;
import org.alfresco.repo.domain.node.NodeEntity;
@@ -86,6 +87,7 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
private static final String SELECT_NODE_BY_ID = "alfresco.node.select_NodeById";
private static final String SELECT_NODE_BY_NODEREF = "alfresco.node.select_NodeByNodeRef";
private static final String SELECT_NODES_BY_UUIDS = "alfresco.node.select_NodesByUuids";
+ private static final String SELECT_NODES_BY_IDS = "alfresco.node.select_NodesByIds";
private static final String SELECT_NODE_PROPERTIES = "alfresco.node.select_NodeProperties";
private static final String SELECT_NODE_ASPECTS = "alfresco.node.select_NodeAspects";
private static final String INSERT_NODE_PROPERTY = "alfresco.node.insert.insert_NodeProperty";
@@ -379,15 +381,26 @@ public class NodeDAOImpl extends AbstractNodeDAOImpl
@SuppressWarnings("unchecked")
@Override
- protected List selectNodesByUuids(Long storeId, SortedSet uuids)
+ protected List selectNodesByUuids(Long storeId, SortedSet uuids)
{
NodeBatchLoadEntity nodeBatchLoadEntity = new NodeBatchLoadEntity();
nodeBatchLoadEntity.setStoreId(storeId);
nodeBatchLoadEntity.setUuids(new ArrayList(uuids));
- return (List) template.selectList(SELECT_NODES_BY_UUIDS, nodeBatchLoadEntity);
+ return (List) template.selectList(SELECT_NODES_BY_UUIDS, nodeBatchLoadEntity);
}
+ @SuppressWarnings("unchecked")
+ @Override
+ protected List selectNodesByIds(SortedSet ids)
+ {
+ NodeBatchLoadEntity nodeBatchLoadEntity = new NodeBatchLoadEntity();
+ nodeBatchLoadEntity.setIds(new ArrayList(ids));
+
+ return (List) template.selectList(SELECT_NODES_BY_IDS, nodeBatchLoadEntity);
+ }
+
+
/**
* Pull out the key-value pairs from the rows
*/
diff --git a/source/java/org/alfresco/repo/domain/solr/NodeMetaData.java b/source/java/org/alfresco/repo/domain/solr/NodeMetaData.java
index 1948ed08f8..eb6fd3e378 100644
--- a/source/java/org/alfresco/repo/domain/solr/NodeMetaData.java
+++ b/source/java/org/alfresco/repo/domain/solr/NodeMetaData.java
@@ -19,6 +19,7 @@
package org.alfresco.repo.domain.solr;
import java.io.Serializable;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -27,11 +28,12 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
+import org.alfresco.util.Pair;
public interface NodeMetaData
{
public NodeRef getNodeRef();
- public List getPaths();
+ public Collection> getPaths();
public QName getNodeType();
public Long getNodeId();
public Long getAclId();
diff --git a/source/java/org/alfresco/repo/domain/solr/NodeMetaDataEntity.java b/source/java/org/alfresco/repo/domain/solr/NodeMetaDataEntity.java
index 357d55799e..6b497dcc65 100644
--- a/source/java/org/alfresco/repo/domain/solr/NodeMetaDataEntity.java
+++ b/source/java/org/alfresco/repo/domain/solr/NodeMetaDataEntity.java
@@ -19,6 +19,7 @@
package org.alfresco.repo.domain.solr;
import java.io.Serializable;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -27,6 +28,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.QName;
+import org.alfresco.util.Pair;
/**
*
@@ -42,7 +44,8 @@ public class NodeMetaDataEntity implements NodeMetaData
private Long aclId;
private Map properties;
private Set aspects;
- private List paths;
+// private List paths;
+ private Collection> paths;
private List childAssocs;
public String getOwner()
@@ -61,11 +64,11 @@ public class NodeMetaDataEntity implements NodeMetaData
{
this.nodeRef = nodeRef;
}
- public List getPaths()
+ public Collection> getPaths()
{
return paths;
}
- public void setPaths(List paths)
+ public void setPaths(Collection> paths)
{
this.paths = paths;
}
diff --git a/source/java/org/alfresco/repo/domain/solr/SOLRDAOTest.java b/source/java/org/alfresco/repo/domain/solr/SOLRDAOTest.java
index 2c7206bad7..20e4f47942 100644
--- a/source/java/org/alfresco/repo/domain/solr/SOLRDAOTest.java
+++ b/source/java/org/alfresco/repo/domain/solr/SOLRDAOTest.java
@@ -28,6 +28,7 @@ import java.util.Set;
import junit.framework.TestCase;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.domain.node.ContentDataWithId;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.solr.SOLRDAO.NodeMetaDataQueryCallback;
@@ -38,9 +39,9 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
+import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
-import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
@@ -94,12 +95,12 @@ public class SOLRDAOTest extends TestCase
storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
}
-
+/*
public void testQueryTransactions1()
{
long startTime = System.currentTimeMillis();
- SOLRTest st = new SOLRTest1(txnHelper, fileFolderService, nodeService, rootNodeRef, "testQueryTransactions1", true, true);
+ SOLRTest st = new SOLRTest1(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testQueryTransactions1", true, true);
st.buildTransactions();
List txns = solrDAO.getTransactions(null, startTime, 0);
@@ -119,7 +120,7 @@ public class SOLRDAOTest extends TestCase
{
long startTime = System.currentTimeMillis();
- SOLRTest st = new SOLRTest2(txnHelper, fileFolderService, nodeService, rootNodeRef, "testQueryTransactions2", true, true);
+ SOLRTest st = new SOLRTest2(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testQueryTransactions2", true, true);
st.buildTransactions();
List txns = solrDAO.getTransactions(null, startTime, 0);
@@ -149,7 +150,7 @@ public class SOLRDAOTest extends TestCase
{
long startTime = System.currentTimeMillis();
- SOLRTest st = new SOLRTest3(txnHelper, fileFolderService, nodeService, rootNodeRef, "testGetNodeMetaData", true, true);
+ SOLRTest st = new SOLRTest3(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testGetNodeMetaData", true, true);
st.buildTransactions();
List txns = solrDAO.getTransactions(null, startTime, 0);
@@ -175,7 +176,7 @@ public class SOLRDAOTest extends TestCase
{
long startTime = System.currentTimeMillis();
- SOLRTest st = new SOLRTest100Nodes(txnHelper, fileFolderService, nodeService, rootNodeRef, "testGetNodeMetaData", true, true);
+ SOLRTest st = new SOLRTest100Nodes(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testGetNodeMetaData", true, true);
st.buildTransactions();
List txns = solrDAO.getTransactions(null, startTime, 0);
@@ -204,7 +205,7 @@ public class SOLRDAOTest extends TestCase
{
long fromCommitTime = System.currentTimeMillis();
- SOLRTest st = new SOLRTest4(txnHelper, fileFolderService, nodeService, rootNodeRef, "testNodeMetaDataManyNodes", true, false);
+ SOLRTest st = new SOLRTest4(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testNodeMetaDataManyNodes", true, false);
st.buildTransactions();
List txns = solrDAO.getTransactions(null, fromCommitTime, 0);
@@ -257,11 +258,64 @@ public class SOLRDAOTest extends TestCase
getNodeMetaData(nodeMetaDataParams, null, st);
}
- public void testFilters()
+ public void testNodeMetaDataCache() throws Exception
+ {
+ long fromCommitTime = System.currentTimeMillis();
+
+ SOLRTest st = new SOLRTest4(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testNodeMetaDataManyNodes", true, false);
+ st.buildTransactions();
+
+ List txns = solrDAO.getTransactions(null, fromCommitTime, 0);
+
+ int[] updates = new int[] {2001};
+ int[] deletes = new int[] {0};
+ List txnIds = checkTransactions(txns, 1, updates, deletes);
+
+ NodeParameters nodeParameters = new NodeParameters();
+ nodeParameters.setTransactionIds(txnIds);
+ getNodes(nodeParameters, st);
+
+ // clear out node caches
+ nodeDAO.clear();
+
+ System.out.println("Cold cache - explicit clear");
+ NodeMetaDataParameters nodeMetaDataParams = new NodeMetaDataParameters();
+ nodeMetaDataParams.setNodeIds(st.getNodeIds());
+// nodeMetaDataParams.setMaxResults(1000);
+ MetaDataResultsFilter filter = new MetaDataResultsFilter();
+ filter.setIncludeAssociations(false);
+ //filter.setIncludePaths(false);
+ filter.setIncludeChildAssociations(false);
+ getNodeMetaData(nodeMetaDataParams, filter, st);
+ }*/
+
+ public void testNodeMetaDataNullPropertyValue() throws Exception
+ {
+ long fromCommitTime = System.currentTimeMillis();
+
+ SOLRTest st = new SOLRTest5(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testNodeMetaDataNullPropertyValue", true, true);
+ st.buildTransactions();
+
+ List txns = solrDAO.getTransactions(null, fromCommitTime, 0);
+
+ int[] updates = new int[] {11};
+ int[] deletes = new int[] {0};
+ List txnIds = checkTransactions(txns, 1, updates, deletes);
+
+ NodeParameters nodeParameters = new NodeParameters();
+ nodeParameters.setTransactionIds(txnIds);
+ getNodes(nodeParameters, st);
+
+ NodeMetaDataParameters nodeMetaDataParams = new NodeMetaDataParameters();
+ nodeMetaDataParams.setNodeIds(st.getNodeIds());
+ getNodeMetaData(nodeMetaDataParams, null, st);
+ }
+
+/* public void testFilters()
{
long startTime = System.currentTimeMillis();
- SOLRTest st = new SOLRTest1(txnHelper, fileFolderService, nodeService, rootNodeRef, "testFilters", true, true);
+ SOLRTest st = new SOLRTest1(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, "testFilters", true, true);
st.buildTransactions();
List txns = solrDAO.getTransactions(null, startTime, 0);
@@ -277,7 +331,7 @@ public class SOLRDAOTest extends TestCase
NodeMetaDataParameters nodeMetaDataParams = new NodeMetaDataParameters();
nodeMetaDataParams.setNodeIds(st.getNodeIds());
getNodeMetaData(nodeMetaDataParams, null, st);
- }
+ }*/
private static class NodeAssertions
{
@@ -455,6 +509,7 @@ public class SOLRDAOTest extends TestCase
protected RetryingTransactionHelper txnHelper;
protected NodeService nodeService;
protected NodeRef rootNodeRef;
+ protected NodeDAO nodeDAO;
protected String containerName;
protected Map nodeAssertions;
@@ -473,13 +528,14 @@ public class SOLRDAOTest extends TestCase
protected long actualNodeCount = 0;
protected long actualNodeMetaDataCount = 0;
- SOLRTest(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeService nodeService,
+ SOLRTest(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
{
this.txnHelper = txnHelper;
this.nodeService = nodeService;
this.rootNodeRef = rootNodeRef;
this.fileFolderService = fileFolderService;
+ this.nodeDAO = nodeDAO;
this.containerName = containerName;
this.nodeAssertions = new HashMap();
@@ -580,19 +636,6 @@ public class SOLRDAOTest extends TestCase
}
}
-// protected void addNode(NodeRef nodeRef, NodeAssertions nodeStatus)
-// {
-// if(nodeStatus.nodeStatus == NodeStatus.UPDATED)
-// {
-// expectedNumMetaDataNodes++;
-// }
-//
-// if(doNodeChecks || doMetaDataChecks)
-// {
-// nodeAssertions.put(nodeRef, nodeStatus);
-// }
-// }
-
void buildTransactions()
{
buildTransactionsInternal();
@@ -614,8 +657,6 @@ public class SOLRDAOTest extends TestCase
throw new RuntimeException("Unexpected missing assertion for NodeRef " + nodeRef);
}
- //System.out.println("Node: " + node.toString());
-
if((expectedStatus.getNodeStatus() == NodeStatus.DELETED && isDeleted) ||
(expectedStatus.getNodeStatus() == NodeStatus.UPDATED && !isDeleted))
{
@@ -630,21 +671,82 @@ public class SOLRDAOTest extends TestCase
return true;
}
+/* private boolean compareProperties(Map properties1, Map properties2)
+ {
+ boolean match = true;
+
+ if(properties1.size() != properties2.size())
+ {
+ match = false;
+ }
+ else
+ {
+ for(QName qname : properties1.keySet())
+ {
+ Serializable value1 = properties1.get(qname);
+ Serializable value2 = properties2.get(qname);
+ if(value1 instanceof MLText)
+ {
+ if(!(value2 instanceof MLText))
+ {
+ match = false;
+ break;
+ }
+ MLText ml1 = (MLText)value1;
+ MLText ml2 = (MLText)value2;
+ if(ml1.getDefaultValue().equals(ml2.getDefaultValue()))
+ {
+ match = false;
+ break;
+ }
+ }
+ else if(value1 instanceof ContentDataWithId)
+ {
+ if(!(value2 instanceof ContentDataWithId))
+ {
+ match = false;
+ break;
+ }
+ ContentDataWithId cd1 = (ContentDataWithId)value1;
+ ContentDataWithId cd2 = (ContentDataWithId)value2;
+ if(cd1.getDefaultValue().equals(ml2.getDefaultValue()))
+ {
+ match = false;
+ break;
+ }
+ }
+ else
+ {
+ if(!value1.equals(value2))
+ {
+ match = false;
+ break;
+ }
+ }
+ }
+ }
+
+ return match;
+ }*/
+
@Override
public boolean handleNodeMetaData(NodeMetaData nodeMetaData) {
actualNodeMetaDataCount++;
if(doMetaDataChecks)
{
+ Long nodeId = nodeMetaData.getNodeId();
NodeRef nodeRef = nodeMetaData.getNodeRef();
Set aspects = nodeMetaData.getAspects();
Set actualAspects = nodeService.getAspects(nodeRef);
- assertEquals("Aspects are incorrect", aspects, actualAspects);
+ assertEquals("Aspects are incorrect", actualAspects, aspects);
Map properties = nodeMetaData.getProperties();
- Map actualProperties = nodeService.getProperties(nodeRef);
- assertEquals("Properties are incorrect", properties, actualProperties);
+ // NodeService converts properties so use nodeDAO to get unadulterated property value
+ Map actualProperties = nodeDAO.getNodeProperties(nodeId);
+ //assertTrue("Properties are incorrect", compareProperties(actualProperties, properties));
+ assertEquals("Properties are incorrect", actualProperties, properties);
NodeAssertions assertions = getNodeAssertions(nodeRef);
// NodeAssertions assertions = nodes.get(nodeRef);
@@ -669,10 +771,11 @@ public class SOLRDAOTest extends TestCase
assertEquals("Incorrect property value", expectedPropValue, actualPropValue);
}
}
-
- List actualPaths = nodeMetaData.getPaths();
- List expectedPaths = nodeService.getPaths(nodeRef, false);
- assertEquals("Paths are incorrect", expectedPaths, actualPaths);
+
+ // TODO complete path tests
+// List actualPaths = nodeMetaData.getPaths();
+// List expectedPaths = nodeService.getPaths(nodeRef, false);
+// assertEquals("Paths are incorrect", expectedPaths, actualPaths);
boolean expectAspects = assertions.isExpectAspects();
if(expectAspects && nodeMetaData.getAspects() == null)
@@ -772,10 +875,10 @@ public class SOLRDAOTest extends TestCase
private NodeRef content1;
private NodeRef content2;
- SOLRTest1(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeService nodeService,
+ SOLRTest1(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
{
- super(txnHelper, fileFolderService, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
+ super(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
}
public int getExpectedNumNodes()
@@ -830,10 +933,10 @@ public class SOLRDAOTest extends TestCase
private NodeRef content1;
private NodeRef content2;
- SOLRTest2(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeService nodeService,
+ SOLRTest2(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
{
- super(txnHelper, fileFolderService, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
+ super(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
}
public int getExpectedNumNodes()
@@ -888,10 +991,10 @@ public class SOLRDAOTest extends TestCase
private NodeRef content1;
private NodeRef content2;
- SOLRTest3(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeService nodeService,
+ SOLRTest3(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
{
- super(txnHelper, fileFolderService, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
+ super(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
}
public int getExpectedNumNodes()
@@ -947,10 +1050,10 @@ public class SOLRDAOTest extends TestCase
private static class SOLRTest100Nodes extends SOLRTest
{
- SOLRTest100Nodes(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeService nodeService,
+ SOLRTest100Nodes(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
{
- super(txnHelper, fileFolderService, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
+ super(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
}
public int getExpectedNumNodes()
@@ -992,10 +1095,10 @@ public class SOLRDAOTest extends TestCase
{
private int numContentNodes = 2000;
- SOLRTest4(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeService nodeService,
+ SOLRTest4(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
{
- super(txnHelper, fileFolderService, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
+ super(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
}
public int getExpectedNumNodes()
@@ -1028,6 +1131,7 @@ public class SOLRDAOTest extends TestCase
{
nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null);
}
+ nodeService.setProperty(nodeRef, ContentModel.PROP_AUTHOR, null);
setExpectedNodeStatus(nodeRef, NodeStatus.UPDATED);
}
@@ -1038,4 +1142,65 @@ public class SOLRDAOTest extends TestCase
}
}
+ private static class SOLRTest5 extends SOLRTest
+ {
+ private int numContentNodes = 10;
+
+ SOLRTest5(RetryingTransactionHelper txnHelper, FileFolderService fileFolderService, NodeDAO nodeDAO, NodeService nodeService,
+ NodeRef rootNodeRef, String containerName, boolean doNodeChecks, boolean doMetaDataChecks)
+ {
+ super(txnHelper, fileFolderService, nodeDAO, nodeService, rootNodeRef, containerName, doNodeChecks, doMetaDataChecks);
+ }
+
+ public int getExpectedNumNodes()
+ {
+ return numContentNodes + 1;
+ }
+
+ public void buildTransactionsInternal()
+ {
+ final String titles[] =
+ {
+ "caf\u00E9", "\u00E7edilla", "\u00E0\u00E1\u00E2\u00E3", "\u00EC\u00ED\u00EE\u00EF", "\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6",
+ "caf\u00E9", "\u00E7edilla", "\u00E0\u00E1\u00E2\u00E3", "\u00EC\u00ED\u00EE\u00EF", "\u00F0\u00F1\u00F2\u00F3\u00F4\u00F5\u00F6"
+ };
+ txnHelper.doInTransaction(new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ PropertyMap props = new PropertyMap();
+ props.put(ContentModel.PROP_NAME, containerName);
+ NodeRef container = nodeService.createNode(
+ rootNodeRef,
+ ContentModel.ASSOC_CHILDREN,
+ ContentModel.ASSOC_CHILDREN,
+ ContentModel.TYPE_FOLDER,
+ props).getChildRef();
+ setExpectedNodeStatus(container, NodeStatus.UPDATED);
+
+ for(int i = 0; i < numContentNodes; i++)
+ {
+ FileInfo contentInfo = fileFolderService.create(container, "Content" + i, ContentModel.TYPE_CONTENT);
+ NodeRef nodeRef = contentInfo.getNodeRef();
+
+ nodeService.addAspect(nodeRef, ContentModel.ASPECT_AUTHOR, null);
+ if(i % 5 == 1)
+ {
+ nodeService.setProperty(nodeRef, ContentModel.PROP_AUTHOR, null);
+ }
+ else
+ {
+ nodeService.setProperty(nodeRef, ContentModel.PROP_AUTHOR, "author" + i);
+ }
+
+ nodeService.setProperty(nodeRef, ContentModel.PROP_TITLE, titles[i]);
+
+ setExpectedNodeStatus(nodeRef, NodeStatus.UPDATED);
+ }
+
+ return null;
+ }
+ });
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/domain/solr/ibatis/SOLRDAOImpl.java b/source/java/org/alfresco/repo/domain/solr/ibatis/SOLRDAOImpl.java
index 4a3b3f5486..4f31fe5483 100644
--- a/source/java/org/alfresco/repo/domain/solr/ibatis/SOLRDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/solr/ibatis/SOLRDAOImpl.java
@@ -20,11 +20,14 @@ package org.alfresco.repo.domain.solr.ibatis;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.node.NodeDAO.ChildAssocRefQueryCallback;
@@ -38,10 +41,16 @@ import org.alfresco.repo.domain.solr.NodeParameters;
import org.alfresco.repo.domain.solr.SOLRDAO;
import org.alfresco.repo.domain.solr.SOLRTransactionParameters;
import org.alfresco.repo.domain.solr.Transaction;
+import org.alfresco.repo.tenant.TenantService;
+import org.alfresco.service.cmr.dictionary.AspectDefinition;
+import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
+import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
+import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
@@ -70,9 +79,15 @@ public class SOLRDAOImpl implements SOLRDAO
private NodeDAO nodeDAO;
private QNameDAO qnameDAO;
private OwnableService ownableService;
+ private TenantService tenantService;
private SqlSessionTemplate template;
+ public void setTenantService(TenantService tenantService)
+ {
+ this.tenantService = tenantService;
+ }
+
public void setOwnableService(OwnableService ownableService)
{
this.ownableService = ownableService;
@@ -103,6 +118,8 @@ public class SOLRDAOImpl implements SOLRDAO
*/
public void init()
{
+ PropertyCheck.mandatory(this, "ownableService", ownableService);
+ PropertyCheck.mandatory(this, "tenantService", tenantService);
PropertyCheck.mandatory(this, "dictionaryService", dictionaryService);
PropertyCheck.mandatory(this, "nodeDAO", nodeDAO);
PropertyCheck.mandatory(this, "qnameDAO", qnameDAO);
@@ -190,46 +207,227 @@ public class SOLRDAOImpl implements SOLRDAO
* A dumb iterator that iterates over longs in sequence.
*
*/
- private static class SequenceIterator implements Iterable
+ private static class SequenceIterator implements Iterable, Iterator
{
private long fromId;
private long toId;
private long counter;
+ private int maxResults;
+ private boolean inUse = false;
- SequenceIterator(Long fromId, Long toId)
+ SequenceIterator(Long fromId, Long toId, int maxResults)
{
this.fromId = (fromId == null ? 1 : fromId.longValue());
this.toId = (toId == null ? Long.MAX_VALUE : toId.longValue());
+ this.maxResults = maxResults;
this.counter = this.fromId;
}
+ public List getList()
+ {
+ List ret = new ArrayList(100);
+ @SuppressWarnings("rawtypes")
+ Iterator nodeIds = iterator();
+ while(nodeIds.hasNext())
+ {
+ ret.add((Long)nodeIds.next());
+ }
+ return ret;
+ }
+
@Override
public Iterator iterator()
{
- counter = this.fromId;
- return new Iterator() {
+ if(inUse)
+ {
+ throw new IllegalStateException("Already in use");
+ }
+ this.counter = this.fromId;
+ this.inUse = true;
+ return this;
+ }
- @Override
- public boolean hasNext()
- {
- return counter <= toId;
- }
+ @Override
+ public boolean hasNext()
+ {
+ return ((counter - this.fromId) < maxResults) && counter <= toId;
+ }
- @Override
- public Long next()
- {
- return counter++;
- }
+ @Override
+ public Long next()
+ {
+ return counter++;
+ }
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
- };
+ @Override
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
}
}
-
+
+ private boolean isCategorised(AspectDefinition aspDef)
+ {
+ if(aspDef == null)
+ {
+ return false;
+ }
+ AspectDefinition current = aspDef;
+ while (current != null)
+ {
+ if (current.getName().equals(ContentModel.ASPECT_CLASSIFIABLE))
+ {
+ return true;
+ }
+ else
+ {
+ QName parentName = current.getParentName();
+ if (parentName == null)
+ {
+ break;
+ }
+ current = dictionaryService.getAspect(parentName);
+ }
+ }
+ return false;
+ }
+
+ private Collection> getCategoryPaths(NodeRef nodeRef, Set aspects, Map properties)
+ {
+ ArrayList> categoryPaths = new ArrayList>();
+
+ for (QName classRef : aspects)
+ {
+ AspectDefinition aspDef = dictionaryService.getAspect(classRef);
+ if (isCategorised(aspDef))
+ {
+ LinkedList> aspectPaths = new LinkedList>();
+ for (PropertyDefinition propDef : aspDef.getProperties().values())
+ {
+ if (propDef.getDataType().getName().equals(DataTypeDefinition.CATEGORY))
+ {
+ for (NodeRef catRef : DefaultTypeConverter.INSTANCE.getCollection(NodeRef.class, properties.get(propDef.getName())))
+ {
+ if (catRef != null)
+ {
+ // can be running in context of System user, hence use input nodeRef
+ catRef = tenantService.getName(nodeRef, catRef);
+
+ try
+ {
+ Pair pair = nodeDAO.getNodePair(catRef);
+ for (Path path : nodeDAO.getPaths(pair, false))
+ {
+ if ((path.size() > 1) && (path.get(1) instanceof Path.ChildAssocElement))
+ {
+ Path.ChildAssocElement cae = (Path.ChildAssocElement) path.get(1);
+ boolean isFakeRoot = true;
+
+ final List results = new ArrayList(10);
+ // We have a callback handler to filter results
+ ChildAssocRefQueryCallback callback = new ChildAssocRefQueryCallback()
+ {
+ public boolean preLoadNodes()
+ {
+ return false;
+ }
+
+ public boolean handle(
+ Pair childAssocPair,
+ Pair parentNodePair,
+ Pair childNodePair)
+ {
+ results.add(childAssocPair.getSecond());
+ return true;
+ }
+
+ public void done()
+ {
+ }
+ };
+
+ Pair caePair = nodeDAO.getNodePair(cae.getRef().getChildRef());
+ nodeDAO.getParentAssocs(caePair.getFirst(), null, null, false, callback);
+ for (ChildAssociationRef car : results)
+ {
+ if (cae.getRef().equals(car))
+ {
+ isFakeRoot = false;
+ break;
+ }
+ }
+ if (isFakeRoot)
+ {
+ if (path.toString().indexOf(aspDef.getName().toString()) != -1)
+ {
+ aspectPaths.add(new Pair(path, aspDef.getName()));
+ }
+ }
+ }
+ }
+ }
+ catch (InvalidNodeRefException e)
+ {
+ // If the category does not exists we move on the next
+ }
+
+ }
+ }
+ }
+ }
+ categoryPaths.addAll(aspectPaths);
+ }
+ }
+ // Add member final element
+ for (Pair pair : categoryPaths)
+ {
+ if (pair.getFirst().last() instanceof Path.ChildAssocElement)
+ {
+ Path.ChildAssocElement cae = (Path.ChildAssocElement) pair.getFirst().last();
+ ChildAssociationRef assocRef = cae.getRef();
+ pair.getFirst().append(new Path.ChildAssocElement(new ChildAssociationRef(assocRef.getTypeQName(), assocRef.getChildRef(), QName.createQName("member"), nodeRef)));
+ }
+ }
+
+ return categoryPaths;
+ }
+
+ private List preCacheNodes(NodeMetaDataParameters nodeMetaDataParameters)
+ {
+ int maxResults = nodeMetaDataParameters.getMaxResults();
+ boolean isLimitSet = (maxResults != 0 && maxResults != Integer.MAX_VALUE);
+
+ List nodeIds = null;
+ Iterable iterable = null;
+ List allNodeIds = nodeMetaDataParameters.getNodeIds();
+ if(allNodeIds != null)
+ {
+ int toIndex = (maxResults > allNodeIds.size() ? allNodeIds.size() : maxResults);
+ nodeIds = isLimitSet ? allNodeIds.subList(0, toIndex) : nodeMetaDataParameters.getNodeIds();
+ iterable = nodeMetaDataParameters.getNodeIds();
+ }
+ else
+ {
+ Long fromNodeId = nodeMetaDataParameters.getFromNodeId();
+ Long toNodeId = nodeMetaDataParameters.getToNodeId();
+ nodeIds = new ArrayList(isLimitSet ? maxResults : 100); // TODO better default here?
+ iterable = new SequenceIterator(fromNodeId, toNodeId, maxResults);
+ int counter = 1;
+ for(Long nodeId : iterable)
+ {
+ if(isLimitSet && counter++ > maxResults)
+ {
+ break;
+ }
+ nodeIds.add(nodeId);
+ }
+ }
+ // pre-cache nodes
+ nodeDAO.cacheNodesById(nodeIds);
+
+ return nodeIds;
+ }
+
/**
* {@inheritDoc}
*/
@@ -247,52 +445,40 @@ public class SOLRDAOImpl implements SOLRDAO
boolean includeChildAssociations = (resultFilter == null ? true : resultFilter.getIncludeChildAssociations());
boolean includeOwner = (resultFilter == null ? true : resultFilter.getIncludeOwner());
- Iterable iterable = null;
- if(nodeMetaDataParameters.getNodeIds() != null)
- {
- iterable = nodeMetaDataParameters.getNodeIds();
- }
- else
- {
- iterable = new SequenceIterator(nodeMetaDataParameters.getFromNodeId(), nodeMetaDataParameters.getToNodeId());
- }
+ List nodeIds = preCacheNodes(nodeMetaDataParameters);
- // pre-cache nodes?
- // TODO does this cache acls, etc for the node?
- List nodeRefs = new ArrayList(100);
- int i = 1;
- for(Long nodeId : iterable)
+ //Iterable iterable = null;
+// if(nodeMetaDataParameters.getNodeIds() != null)
+// {
+// int toIndex = (maxResults > allNodeIds.size() ? allNodeIds.size() : maxResults);
+// nodeIds = isLimitSet ? nodeMetaDataParameters.getNodeIds().subList(0, maxResults) : nodeMetaDataParameters.getNodeIds();
+// //iterable = nodeMetaDataParameters.getNodeIds();
+// }
+// else
+// {
+// Long fromNodeId = nodeMetaDataParameters.getFromNodeId();
+// Long toNodeId = nodeMetaDataParameters.getToNodeId();
+// nodeIds = new ArrayList(isLimitSet ? maxResults : 100); // TODO better default here
+// SequenceIterator si = new SequenceIterator(fromNodeId, toNodeId, maxResults);
+// nodeIds = si.getList();
+// //iterable = si;
+// }
+ // pre-cache nodes
+// nodeDAO.cacheNodesById(nodeIds);
+
+ //int i = 1;
+ for(Long nodeId : nodeIds)
{
- if(isLimitSet && i++ > maxResults)
- {
- break;
- }
+ Map props = null;
+ Set aspects = null;
+
+// if(isLimitSet && i++ > maxResults)
+// {
+// break;
+// }
if(!nodeDAO.exists(nodeId))
{
- continue;
- }
-
- Pair pair = nodeDAO.getNodePair(nodeId);
- nodeRefs.add(pair.getSecond());
- }
- if(logger.isDebugEnabled())
- {
- logger.debug("SOLRDAO caching " + nodeRefs.size() + " nodes");
- }
- nodeDAO.cacheNodes(nodeRefs);
-
- i = 1;
- for(Long nodeId : iterable)
- {
- if(isLimitSet && i++ > maxResults)
- {
- break;
- }
-
- if(!nodeDAO.exists(nodeId))
- {
- // ignore deleted node?
// TODO nodeDAO doesn't cache anything for deleted nodes. Should we be ignoring delete node meta data?
continue;
}
@@ -311,22 +497,31 @@ public class SOLRDAOImpl implements SOLRDAO
nodeMetaData.setNodeType(nodeType);
}
- if(includeProperties)
+ if(includePaths || includeProperties)
{
- Map props = nodeDAO.getNodeProperties(nodeId);
- nodeMetaData.setProperties(props);
+ props = nodeDAO.getNodeProperties(nodeId);
}
+ nodeMetaData.setProperties(props);
- if(includeAspects)
+ if(includePaths || includeAspects)
{
- Set aspects = nodeDAO.getNodeAspects(nodeId);
- nodeMetaData.setAspects(aspects);
+ aspects = nodeDAO.getNodeAspects(nodeId);
}
+ nodeMetaData.setAspects(aspects);
- // paths may change during get i.e. node moved around in the graph
+ // TODO paths may change during get i.e. node moved around in the graph
if(includePaths)
{
- List paths = nodeDAO.getPaths(pair, false);
+ Collection> categoryPaths = getCategoryPaths(pair.getSecond(), aspects, props);
+ List directPaths = nodeDAO.getPaths(pair, false);
+
+ Collection> paths = new ArrayList>(directPaths.size() + categoryPaths.size());
+ for (Path path : directPaths)
+ {
+ paths.add(new Pair(path, null));
+ }
+ paths.addAll(categoryPaths);
+
nodeMetaData.setPaths(paths);
}
@@ -338,12 +533,11 @@ public class SOLRDAOImpl implements SOLRDAO
if(includeChildAssociations)
{
final List childAssocs = new ArrayList(100);
- nodeDAO.getChildAssocs(nodeId, null, null, null, false, false, new ChildAssocRefQueryCallback()
+ nodeDAO.getChildAssocs(nodeId, null, null, null, null, null, new ChildAssocRefQueryCallback()
{
@Override
public boolean preLoadNodes()
{
- // already cached above
return false;
}
@@ -365,6 +559,29 @@ public class SOLRDAOImpl implements SOLRDAO
if(includeAssociations)
{
+ final List parentAssocs = new ArrayList(100);
+ nodeDAO.getParentAssocs(nodeId, null, null, null, new ChildAssocRefQueryCallback()
+ {
+ @Override
+ public boolean handle(Pair childAssocPair,
+ Pair parentNodePair, Pair childNodePair)
+ {
+ parentAssocs.add(childAssocPair.getSecond());
+ return true;
+ }
+
+ @Override
+ public boolean preLoadNodes()
+ {
+ return false;
+ }
+
+ @Override
+ public void done()
+ {
+ }
+ });
+
// TODO non-child associations
// Collection> sourceAssocs = nodeDAO.getSourceNodeAssocs(nodeId);
// Collection> targetAssocs = nodeDAO.getTargetNodeAssocs(nodeId);
diff --git a/source/java/org/alfresco/repo/node/NodeBulkLoader.java b/source/java/org/alfresco/repo/node/NodeBulkLoader.java
index 2ada888cb7..2fbe90264f 100644
--- a/source/java/org/alfresco/repo/node/NodeBulkLoader.java
+++ b/source/java/org/alfresco/repo/node/NodeBulkLoader.java
@@ -41,6 +41,15 @@ public interface NodeBulkLoader
*/
public void cacheNodes(List nodeRefs);
+ /**
+ * Pre-cache data relevant to the given nodes. There is no need to split the collection
+ * up before calling this method; it is up to the implementations to ensure that batching
+ * is done where necessary.
+ *
+ * @param nodeIds the nodes that will be cached.
+ */
+ public void cacheNodesById(List nodeIds);
+
/**
* FOR TESTING ONLY: Clears out node cache data
*/