diff --git a/source/java/org/alfresco/repo/usage/ContentUsageImpl.java b/source/java/org/alfresco/repo/usage/ContentUsageImpl.java index 8cfd46e6b7..f36220ec73 100644 --- a/source/java/org/alfresco/repo/usage/ContentUsageImpl.java +++ b/source/java/org/alfresco/repo/usage/ContentUsageImpl.java @@ -32,6 +32,7 @@ import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.security.authentication.AuthenticationContext; import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -53,7 +54,8 @@ import org.apache.commons.logging.LogFactory; public class ContentUsageImpl implements ContentUsageService, NodeServicePolicies.OnUpdatePropertiesPolicy, NodeServicePolicies.BeforeDeleteNodePolicy, - NodeServicePolicies.OnAddAspectPolicy + NodeServicePolicies.OnAddAspectPolicy, + NodeServicePolicies.OnCreateNodePolicy { // Logger private static Log logger = LogFactory.getLog(ContentUsageImpl.class); @@ -61,11 +63,8 @@ public class ContentUsageImpl implements ContentUsageService, /** Key to the deleted nodes */ private static final String KEY_DELETED_NODES = "contentUsage.deletedNodes"; - /** Key to the updated nodes */ - private static final String KEY_UPDATED_NODES = "contentUsage.updatedNodes"; - - /** Key to the deleted folder */ - private static final String KEY_DELETED_FOLDER = "contentUsage.deletedFolder"; + /** Key to the created nodes */ + private static final String KEY_CREATED_NODES = "contentUsage.createdNodes"; private NodeService nodeService; private PersonService personService; @@ -107,12 +106,12 @@ public class ContentUsageImpl implements ContentUsageService, { this.tenantService = tenantService; } - + public void setEnabled(boolean enabled) { this.enabled = enabled; } - + public void setStores(List stores) { this.stores = stores; @@ -127,7 +126,7 @@ public class ContentUsageImpl implements ContentUsageService, * The initialise method */ public void init() - { + { if (enabled) { // Register interest in the onUpdateProperties policy - for content @@ -142,18 +141,17 @@ public class ContentUsageImpl implements ContentUsageService, ContentModel.TYPE_CONTENT, new JavaBehaviour(this, "beforeDeleteNode")); - // Register interest in the beforeDeleteNode policy - for folder + // Register interest in the onCreateNode policy - for content policyComponent.bindClassBehaviour( - QName.createQName(NamespaceService.ALFRESCO_URI, "beforeDeleteNode"), - ContentModel.TYPE_FOLDER, - new JavaBehaviour(this, "beforeDeleteNode")); + QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), + ContentModel.TYPE_CONTENT, + new JavaBehaviour(this, "onCreateNode")); // Register interest in the onAddAspect policy - for ownable policyComponent.bindClassBehaviour( QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onAddAspect")); - } } @@ -167,6 +165,12 @@ public class ContentUsageImpl implements ContentUsageService, AlfrescoTransactionSupport.bindResource(KEY_DELETED_NODES, deletedNodes); } deletedNodes.add(tenantService.getName(nodeRef)); + + Set updatedNodes = (Set)AlfrescoTransactionSupport.getResource(KEY_CREATED_NODES); + if (updatedNodes != null) + { + updatedNodes.remove(tenantService.getName(nodeRef)); + } } @SuppressWarnings("unchecked") @@ -187,16 +191,64 @@ public class ContentUsageImpl implements ContentUsageService, return false; } - @SuppressWarnings("unchecked") - private void recordUpdate(NodeRef nodeRef) + public void onCreateNode(ChildAssociationRef childAssocRef) { - Set updatedNodes = (Set)AlfrescoTransactionSupport.getResource(KEY_UPDATED_NODES); - if (updatedNodes == null) + NodeRef nodeRef = childAssocRef.getChildRef(); + if (stores.contains(tenantService.getBaseName(nodeRef.getStoreRef()).toString()) && (! alreadyCreated(nodeRef))) { - updatedNodes = new HashSet(); - AlfrescoTransactionSupport.bindResource(KEY_UPDATED_NODES, updatedNodes); + // TODO use data dictionary to get content property + ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); + + if (contentData != null) + { + long contentSize = contentData.getSize(); + + // Get owner/creator + String owner = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_OWNER); + if ((owner == null) || (owner.equals(OwnableService.NO_OWNER))) + { + owner = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_CREATOR); + } + + if (contentSize != 0 && owner != null) + { + // increment usage if node is being created + if (logger.isDebugEnabled()) logger.debug("onCreateNode: nodeRef="+nodeRef+", owner="+owner+", contentSize="+contentSize); + incrementUserUsage(owner, contentSize, nodeRef); + recordCreate(nodeRef); + } + } } - updatedNodes.add(tenantService.getName(nodeRef)); + } + + @SuppressWarnings("unchecked") + private void recordCreate(NodeRef nodeRef) + { + Set createdNodes = (Set)AlfrescoTransactionSupport.getResource(KEY_CREATED_NODES); + if (createdNodes == null) + { + createdNodes = new HashSet(); + AlfrescoTransactionSupport.bindResource(KEY_CREATED_NODES, createdNodes); + } + createdNodes.add(tenantService.getName(nodeRef)); + } + + @SuppressWarnings("unchecked") + private boolean alreadyCreated(NodeRef nodeRef) + { + Set createdNodes = (Set)AlfrescoTransactionSupport.getResource(KEY_CREATED_NODES); + if (createdNodes != null) + { + for (NodeRef createdNodeRef : createdNodes) + { + if (createdNodeRef.equals(nodeRef)) + { + if (logger.isDebugEnabled()) logger.debug("alreadyCreated: nodeRef="+nodeRef); + return true; + } + } + } + return false; } /** @@ -211,7 +263,7 @@ public class ContentUsageImpl implements ContentUsageService, Map before, Map after) { - if (stores.contains(tenantService.getBaseName(nodeRef.getStoreRef()).toString())) + if (stores.contains(tenantService.getBaseName(nodeRef.getStoreRef()).toString()) && (! alreadyCreated(nodeRef))) { // Check for change in content size @@ -239,14 +291,12 @@ public class ContentUsageImpl implements ContentUsageService, // new size has been added - note: ownerBefore does not matter since the contentSizeBefore is null if (logger.isDebugEnabled()) logger.debug("onUpdateProperties: updateSize (null -> "+contentSizeAfter+"): nodeRef="+nodeRef+", ownerAfter="+ownerAfter); incrementUserUsage(ownerAfter, contentSizeAfter, nodeRef); - recordUpdate(nodeRef); } else if (contentSizeAfter == null && contentSizeBefore != null && contentSizeBefore != 0 && ownerBefore != null) { // old size has been removed - note: ownerAfter does not matter since contentSizeAfter is null if (logger.isDebugEnabled()) logger.debug("onUpdateProperties: updateSize ("+contentSizeBefore+" -> null): nodeRef="+nodeRef+", ownerBefore="+ownerBefore); decrementUserUsage(ownerBefore, contentSizeBefore, nodeRef); - recordUpdate(nodeRef); } else if (contentSizeBefore != null && contentSizeAfter != null) { @@ -258,12 +308,10 @@ public class ContentUsageImpl implements ContentUsageService, if (contentSizeBefore != 0 && ownerBefore != null) { decrementUserUsage(ownerBefore, contentSizeBefore, nodeRef); - recordUpdate(nodeRef); } if (contentSizeAfter != 0 && ownerAfter != null) { incrementUserUsage(ownerAfter, contentSizeAfter, nodeRef); - recordUpdate(nodeRef); } } else @@ -274,14 +322,12 @@ public class ContentUsageImpl implements ContentUsageService, // new owner has been added if (logger.isDebugEnabled()) logger.debug("onUpdateProperties: updateOwner (null -> "+ownerAfter+"): nodeRef="+nodeRef+", contentSize="+contentSizeAfter); incrementUserUsage(ownerAfter, contentSizeAfter, nodeRef); - recordUpdate(nodeRef); } else if (ownerAfter == null && ownerBefore != null && contentSizeBefore != 0) { // old owner has been removed if (logger.isDebugEnabled()) logger.debug("onUpdateProperties: updateOwner ("+ownerBefore+" -> null): nodeRef="+nodeRef+", contentSize="+contentSizeBefore); decrementUserUsage(ownerBefore, contentSizeBefore, nodeRef); - recordUpdate(nodeRef); } else if (ownerBefore != null && ownerAfter != null && ownerBefore.equals(ownerAfter) == false) { @@ -291,12 +337,10 @@ public class ContentUsageImpl implements ContentUsageService, if (contentSizeBefore != 0) { decrementUserUsage(ownerBefore, contentSizeBefore, nodeRef); - recordUpdate(nodeRef); } if (contentSizeAfter != 0) { incrementUserUsage(ownerAfter, contentSizeAfter, nodeRef); - recordUpdate(nodeRef); } } } @@ -310,39 +354,30 @@ public class ContentUsageImpl implements ContentUsageService, * @param nodeRef the node reference */ public void beforeDeleteNode(NodeRef nodeRef) - { + { if (stores.contains(tenantService.getBaseName(nodeRef.getStoreRef()).toString()) && (! alreadyDeleted(nodeRef))) { - QName type = nodeService.getType(nodeRef); - if (type.equals(ContentModel.TYPE_CONTENT)) + // TODO use data dictionary to get content property + ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); + + if (contentData != null) { - // TODO use data dictionary to get content property - ContentData contentData = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); + long contentSize = contentData.getSize(); - if (contentData != null) + // Get owner/creator + String owner = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_OWNER); + if ((owner == null) || (owner.equals(OwnableService.NO_OWNER))) { - long contentSize = contentData.getSize(); - - // Get owner/creator - String owner = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_OWNER); - if ((owner == null) || (owner.equals(OwnableService.NO_OWNER))) - { - owner = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_CREATOR); - } - - if (contentSize != 0 && owner != null) - { - // decrement usage if node is being deleted - if (logger.isDebugEnabled()) logger.debug("beforeDeleteNode: nodeRef="+nodeRef+", owner="+owner+", contentSize="+contentSize); - decrementUserUsage(owner, contentSize, nodeRef); - recordDelete(nodeRef); - } + owner = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_CREATOR); + } + + if (contentSize != 0 && owner != null) + { + // decrement usage if node is being deleted + if (logger.isDebugEnabled()) logger.debug("beforeDeleteNode: nodeRef="+nodeRef+", owner="+owner+", contentSize="+contentSize); + decrementUserUsage(owner, contentSize, nodeRef); + recordDelete(nodeRef); } - } - else if (type.equals(ContentModel.TYPE_FOLDER)) - { - if (logger.isDebugEnabled()) logger.debug("beforeDeleteNode: folderNodeRef="+nodeRef); - AlfrescoTransactionSupport.bindResource(KEY_DELETED_FOLDER, nodeRef); } } } diff --git a/source/java/org/alfresco/repo/usage/UserUsageTest.java b/source/java/org/alfresco/repo/usage/UserUsageTest.java index 7fb486b096..eb02131964 100644 --- a/source/java/org/alfresco/repo/usage/UserUsageTest.java +++ b/source/java/org/alfresco/repo/usage/UserUsageTest.java @@ -19,6 +19,7 @@ package org.alfresco.repo.usage; +import java.io.InputStream; import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -32,6 +33,7 @@ import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.MutableAuthenticationDao; +import org.alfresco.service.cmr.admin.RepoAdminService; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -72,9 +74,12 @@ public class UserUsageTest extends TestCase private ContentUsageImpl contentUsageImpl; private UsageService usageService; private OwnableService ownableService; + private RepoAdminService repoAdminService; private static final String TEST_USER = "userUsageTestUser"; + private static final QName customType = QName.createQName("{my.new.model}sop"); // from exampleModel.xml + protected void setUp() throws Exception { nodeService = (NodeService) applicationContext.getBean("nodeService"); @@ -95,6 +100,8 @@ public class UserUsageTest extends TestCase ownableService = (OwnableService) applicationContext.getBean("ownableService"); + repoAdminService = (RepoAdminService) applicationContext.getBean("repoAdminService"); + testTX = transactionService.getUserTransaction(); testTX.begin(); this.authenticationComponent.setSystemUserAsCurrentUser(); @@ -119,7 +126,16 @@ public class UserUsageTest extends TestCase } authenticationService.createAuthentication(TEST_USER, TEST_USER.toCharArray()); + // deploy custom model + InputStream modelStream = getClass().getClassLoader().getResourceAsStream("tenant/exampleModel.xml"); + repoAdminService.deployModel(modelStream, "exampleModel.xml"); + + testTX.commit(); + authenticationComponent.clearCurrentSecurityContext(); + + testTX = transactionService.getUserTransaction(); + testTX.begin(); } protected void tearDown() throws Exception @@ -179,7 +195,7 @@ public class UserUsageTest extends TestCase NodeRef content1 = addTextContent(folder, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes"); // + 44 + NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); NodeRef content3 = addTextContent(folder, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 @@ -233,7 +249,7 @@ public class UserUsageTest extends TestCase NodeRef content1 = addTextContent(folder, "tqbfjotld.txt", "The quick brown fox jumps over the lazy dog"); assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - NodeRef content2 = addTextContent(folder, "afdpj.txt", "Amazingly few discotheques provide jukeboxes"); + NodeRef content2 = addTextContent(folder, "afdpj.txt", "Amazingly few discotheques provide jukeboxes", true); assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); NodeRef content3 = addTextContent(folder, "aqabfweatj.txt", "All questions asked by five watch experts amazed the judge"); @@ -276,6 +292,126 @@ public class UserUsageTest extends TestCase assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); } + public void testCreateDeleteRestoreInTx() throws Exception + { + if(!contentUsageImpl.getEnabled()) + { + return; + } + + runAs(TEST_USER); + + assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); + + // Create a folder + Map folderProps = new HashMap(1); + folderProps.put(ContentModel.PROP_NAME, "testFolder"); + NodeRef folder = this.nodeService.createNode( + this.rootNodeRef, + ContentModel.ASSOC_CHILDREN, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder"), + ContentModel.TYPE_FOLDER).getChildRef(); + + // add content + + NodeRef content1 = addTextContent(folder, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 + assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); + + NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 + assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); + + NodeRef content3 = addTextContent(folder, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 + assertEquals(145, contentUsageImpl.getUserUsage(TEST_USER)); + + // delete content in a different order + + delete(content2); // - 44 + assertEquals(101, contentUsageImpl.getUserUsage(TEST_USER)); + + delete(content3); // - 58 + assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); + + delete(content1); // - 43 + assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); + + // restore content in a different order + + restore(content3); // + 58 + assertEquals(58, contentUsageImpl.getUserUsage(TEST_USER)); + + restore(content1); // + 43 + assertEquals(101, contentUsageImpl.getUserUsage(TEST_USER)); + + restore(content2); // - 44 + assertEquals(145, contentUsageImpl.getUserUsage(TEST_USER)); + } + + public void testCreateDeleteRestoreAcrossTx() throws Exception + { + if(!contentUsageImpl.getEnabled()) + { + return; + } + + runAs(TEST_USER); + + assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); + + // Create a folder + Map folderProps = new HashMap(1); + folderProps.put(ContentModel.PROP_NAME, "testFolder"); + NodeRef folder = this.nodeService.createNode( + this.rootNodeRef, + ContentModel.ASSOC_CHILDREN, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testFolder"), + ContentModel.TYPE_FOLDER).getChildRef(); + + // add content + + NodeRef content1 = addTextContent(folder, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 + assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); + + NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 + assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); + + NodeRef content3 = addTextContent(folder, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 + assertEquals(145, contentUsageImpl.getUserUsage(TEST_USER)); + + testTX.commit(); + + testTX = transactionService.getUserTransaction(); + testTX.begin(); + runAs(TEST_USER); + + // delete content in a different order + + delete(content2); // - 44 + assertEquals(101, contentUsageImpl.getUserUsage(TEST_USER)); + + delete(content3); // - 58 + assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); + + delete(content1); // - 43 + assertEquals(0, contentUsageImpl.getUserUsage(TEST_USER)); + + testTX.commit(); + + testTX = transactionService.getUserTransaction(); + testTX.begin(); + runAs(TEST_USER); + + // restore content in a different order + + restore(content3); // + 58 + assertEquals(58, contentUsageImpl.getUserUsage(TEST_USER)); + + restore(content1); // + 43 + assertEquals(101, contentUsageImpl.getUserUsage(TEST_USER)); + + restore(content2); // - 44 + assertEquals(145, contentUsageImpl.getUserUsage(TEST_USER)); + } + public void testCreateCopyDeleteInTx() throws Exception { if(!contentUsageImpl.getEnabled()) @@ -348,12 +484,6 @@ public class UserUsageTest extends TestCase NodeRef content1 = addTextContent(folder, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - testTX.commit(); - - testTX = transactionService.getUserTransaction(); - testTX.begin(); - runAs(TEST_USER); - // copy content NodeRef content2 = copy(content1, folder, "Copy of text1.txt"); // + 43 @@ -362,14 +492,6 @@ public class UserUsageTest extends TestCase NodeRef content3 = copy(content1, folder, "Copy of Copy of text1.txt"); // + 43 assertEquals(129, contentUsageImpl.getUserUsage(TEST_USER)); - testTX.commit(); - - testTX = transactionService.getUserTransaction(); - testTX.begin(); - runAs(TEST_USER); - - assertEquals(129, contentUsageImpl.getUserUsage(TEST_USER)); - // delete content delete(content2); // - 43 @@ -407,7 +529,7 @@ public class UserUsageTest extends TestCase addTextContent(folder1, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - addTextContent(folder1, "text2.txt", "Amazingly few discotheques provide jukeboxes"); // + 44 + addTextContent(folder1, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); addTextContent(folder1, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 @@ -454,7 +576,7 @@ public class UserUsageTest extends TestCase addTextContent(folder1, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - addTextContent(folder1, "text2.txt", "Amazingly few discotheques provide jukeboxes"); // + 44 + addTextContent(folder1, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); addTextContent(folder1, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 @@ -519,7 +641,7 @@ public class UserUsageTest extends TestCase NodeRef content1 = addTextContent(folder, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes"); // + 44 + NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); NodeRef content3 = addTextContent(folder, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 @@ -579,7 +701,7 @@ public class UserUsageTest extends TestCase NodeRef content1 = addTextContent(folder, "text1.txt", "The quick brown fox jumps over the lazy dog"); // + 43 assertEquals(43, contentUsageImpl.getUserUsage(TEST_USER)); - NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes"); // + 44 + NodeRef content2 = addTextContent(folder, "text2.txt", "Amazingly few discotheques provide jukeboxes", true); // + 44 assertEquals(87, contentUsageImpl.getUserUsage(TEST_USER)); NodeRef content3 = addTextContent(folder, "text3.txt", "All questions asked by five watch experts amazed the judge"); // + 58 @@ -625,6 +747,11 @@ public class UserUsageTest extends TestCase } private NodeRef addTextContent(NodeRef folderRef, String name, String textData) + { + return addTextContent(folderRef, name, textData, false); + } + + private NodeRef addTextContent(NodeRef folderRef, String name, String textData, boolean custom) { Map contentProps = new HashMap(); contentProps.put(ContentModel.PROP_NAME, name); @@ -632,7 +759,7 @@ public class UserUsageTest extends TestCase ChildAssociationRef association = nodeService.createNode(folderRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), - ContentModel.TYPE_CONTENT, + (custom == true ? customType: ContentModel.TYPE_CONTENT), contentProps); NodeRef content = association.getChildRef(); @@ -662,6 +789,14 @@ public class UserUsageTest extends TestCase nodeService.deleteNode(folderOrContentRef); } + private void restore(NodeRef origfolderOrContentRef) + { + NodeRef archiveRootNode = nodeService.getStoreArchiveNode(this.rootNodeRef.getStoreRef()); + + NodeRef archiveNodeRef = new NodeRef(archiveRootNode.getStoreRef(), origfolderOrContentRef.getId()); + nodeService.restoreNode(archiveNodeRef, null, null, null); + } + private NodeRef copy(NodeRef sourceFolderOrContentRef, NodeRef targetFolderRef, String newName) throws FileNotFoundException { return fileFolderService.copy(sourceFolderOrContentRef, targetFolderRef, newName).getNodeRef();