diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml
index 5a35561a63..27e309d1f6 100644
--- a/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml
+++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/rm-action-context.xml
@@ -260,6 +260,7 @@
+
${rm.ghosting.enabled}
@@ -761,7 +762,6 @@
-
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java
index 4a4ebbaab2..3e3ecd1b3e 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java
@@ -17,12 +17,10 @@ import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileNotFoundException;
-import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.util.StringUtils;
/**
@@ -35,9 +33,6 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
{
private static Log logger = LogFactory.getLog(CopyMoveLinkFileToBaseAction.class);
- /** Retrying transaction helper */
- private RetryingTransactionHelper retryingTransactionHelper;
-
/** action parameters */
public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder";
public static final String PARAM_PATH = "path";
@@ -94,14 +89,6 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
this.filePlanService = filePlanService;
}
- /**
- * @param retryingTransactionHelper retrying transaction helper
- */
- public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
- {
- this.retryingTransactionHelper = retryingTransactionHelper;
- }
-
/**
* @see org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase#addParameterDefinitions(java.util.List)
*/
@@ -138,25 +125,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
NodeRef recordFolder = (NodeRef)action.getParameterValue(PARAM_DESTINATION_RECORD_FOLDER);
if (recordFolder == null)
{
- final boolean finaltargetIsUnfiledRecords = targetIsUnfiledRecords;
- recordFolder = retryingTransactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback()
- {
- public NodeRef execute() throws Throwable
- {
- NodeRef result = null;
- try
- {
- // get the reference to the record folder based on the relative path
- result = createOrResolvePath(action, actionedUponNodeRef, finaltargetIsUnfiledRecords);
- }
- catch (DuplicateChildNodeNameException ex)
- {
- throw new ConcurrencyFailureException("Cannot create or resolve path.", ex);
- }
-
- return result;
- }
- }, false, true);
+ recordFolder = createOrResolvePath(action, actionedUponNodeRef, targetIsUnfiledRecords);
}
// now we have the reference to the target folder we can do some final checks to see if the action is valid
@@ -170,30 +139,26 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
{
try
{
- synchronized (this)
+ if (getMode() == CopyMoveLinkFileToActionMode.MOVE)
{
- if (getMode() == CopyMoveLinkFileToActionMode.MOVE)
- {
- fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
- }
- else if (getMode() == CopyMoveLinkFileToActionMode.COPY)
- {
- fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
- }
- else if (getMode() == CopyMoveLinkFileToActionMode.LINK)
- {
- getRecordService().link(actionedUponNodeRef, finalRecordFolder);
- }
+ fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
+ }
+ else if (getMode() == CopyMoveLinkFileToActionMode.COPY)
+ {
+ fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
+ }
+ else if (getMode() == CopyMoveLinkFileToActionMode.LINK)
+ {
+ getRecordService().link(actionedUponNodeRef, finalRecordFolder);
}
}
catch (FileNotFoundException fileNotFound)
{
throw new AlfrescoRuntimeException("Unable to execute file to action, because the " + (mode == CopyMoveLinkFileToActionMode.MOVE ? "move" : "copy") + " operation failed.", fileNotFound);
}
-
+
return null;
}
-
});
}
}
@@ -283,23 +248,29 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
* @param targetisUnfiledRecords true is the target is in unfiled records
* @return
*/
- private NodeRef createOrResolvePath(Action action, NodeRef actionedUponNodeRef, boolean targetisUnfiledRecords)
+ private NodeRef createOrResolvePath(final Action action, final NodeRef actionedUponNodeRef, final boolean targetisUnfiledRecords)
{
// get the starting context
- NodeRef context = getContext(action, actionedUponNodeRef, targetisUnfiledRecords);
+ final NodeRef context = getContext(action, actionedUponNodeRef, targetisUnfiledRecords);
NodeRef path = context;
// get the path we wish to resolve
String pathParameter = (String)action.getParameterValue(PARAM_PATH);
- String[] pathElementsArray = StringUtils.tokenizeToStringArray(pathParameter, "/", false, true);
+ final String[] pathElementsArray = StringUtils.tokenizeToStringArray(pathParameter, "/", false, true);
if((pathElementsArray != null) && (pathElementsArray.length > 0))
{
// get the create parameter
Boolean createValue = (Boolean)action.getParameterValue(PARAM_CREATE_RECORD_PATH);
- boolean create = createValue == null ? false : createValue.booleanValue();
+ final boolean create = createValue == null ? false : createValue.booleanValue();
// create or resolve the specified path
- path = createOrResolvePath(action, context, actionedUponNodeRef, Arrays.asList(pathElementsArray), targetisUnfiledRecords, create, false);
+ path = getTransactionService().getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback()
+ {
+ public NodeRef execute() throws Throwable
+ {
+ return createOrResolvePath(action, context, actionedUponNodeRef, Arrays.asList(pathElementsArray), targetisUnfiledRecords, create, false);
+ }
+ }, false, true);
}
return path;
}
@@ -388,7 +359,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
NodeRef child = getChild(parent, childName);
if (child == null)
{
- if(targetisUnfiledRecords)
+ if (targetisUnfiledRecords)
{
// create unfiled folder
child = fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
diff --git a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java
index 9c91f3586b..ea027ede58 100644
--- a/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java
+++ b/rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java
@@ -29,6 +29,7 @@ import org.alfresco.module.org_alfresco_module_rm.action.RMDispositionActionExec
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
+import org.alfresco.module.org_alfresco_module_rm.record.InplaceRecordService;
import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService;
import org.alfresco.repo.content.cleanup.EagerContentStoreCleaner;
import org.alfresco.service.cmr.action.Action;
@@ -56,10 +57,13 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
/** Capability service */
private CapabilityService capabilityService;
-
+
/** Recordable version service */
private RecordableVersionService recordableVersionService;
+ /** Inplace record service */
+ private InplaceRecordService inplaceRecordService;
+
/** Indicates if ghosting is enabled or not */
private boolean ghostingEnabled = true;
@@ -78,7 +82,7 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
{
this.capabilityService = capabilityService;
}
-
+
/**
* @param recordableVersionService recordable version service
*/
@@ -87,6 +91,14 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
this.recordableVersionService = recordableVersionService;
}
+ /**
+ * @param inplaceRecordService inplace record service
+ */
+ public void setInplaceRecordService(InplaceRecordService inplaceRecordService)
+ {
+ this.inplaceRecordService = inplaceRecordService;
+ }
+
/**
* @param ghostingEnabled true if ghosting is enabled, false otherwise
*/
@@ -169,7 +181,10 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
{
recordableVersionService.destroyRecordedVersion(version);
}
-
+
+ // Hide from inplace users to give the impression of destruction
+ inplaceRecordService.hideRecord(record);
+
// Add the ghosted aspect
getNodeService().addAspect(record, ASPECT_GHOSTED, null);
}
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java
index 74ad459f61..5e5dd27b0a 100755
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java
@@ -50,7 +50,8 @@ import org.junit.runners.Suite.SuiteClasses;
RM1914Test.class,
//RM2190Test.class,
RM2192Test.class,
- RM3314Test.class
+ RM3314Test.class,
+ RM4101Test.class
})
public class IssueTestSuite
{
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4101Test.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4101Test.java
new file mode 100644
index 0000000000..3c302264a3
--- /dev/null
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4101Test.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2005-2016 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
+package org.alfresco.module.org_alfresco_module_rm.test.integration.issue;
+
+import java.util.UUID;
+
+import org.alfresco.module.org_alfresco_module_rm.action.impl.LinkToAction;
+import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
+import org.alfresco.service.cmr.action.Action;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.rule.Rule;
+import org.alfresco.service.cmr.rule.RuleService;
+import org.alfresco.service.cmr.rule.RuleType;
+
+/**
+ * Tests issue #4101: Link to, Copy to and File to rules fail when not run in background
+ *
+ * @author Tuna Aksoy
+ * @since 2.3.0.8
+ */
+public class RM4101Test extends BaseRMTestCase
+{
+ private RuleService ruleService;
+
+ @Override
+ protected void initServices()
+ {
+ super.initServices();
+
+ ruleService = (RuleService) applicationContext.getBean("RuleService");
+ }
+
+ @Override
+ protected boolean isRecordTest()
+ {
+ return true;
+ }
+
+ public void testRunRuleNotInBackground() throws Exception
+ {
+ final String categoryName = "category1" + UUID.randomUUID().toString();
+ final NodeRef category1 = doTestInTransaction(new Test()
+ {
+ @Override
+ public NodeRef run()
+ {
+ return filePlanService.createRecordCategory(filePlan, categoryName);
+ }
+ });
+
+ final NodeRef folder1 = doTestInTransaction(new Test()
+ {
+ @Override
+ public NodeRef run()
+ {
+ return recordFolderService.createRecordFolder(category1, "folder1WithRule" + UUID.randomUUID().toString());
+ }
+ });
+
+ final String folder2Name = "folder2FolderToLinkTo" + UUID.randomUUID().toString();
+ final NodeRef folder2 = doTestInTransaction(new Test()
+ {
+ @Override
+ public NodeRef run()
+ {
+ return recordFolderService.createRecordFolder(category1, folder2Name);
+ }
+ });
+
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run()
+ {
+ Action linkToAction = actionService.createAction(LinkToAction.NAME);
+ linkToAction.setParameterValue(LinkToAction.PARAM_PATH, "/" + categoryName + "/" + folder2Name);
+
+ Rule rule = new Rule();
+ rule.setRuleType(RuleType.INBOUND);
+ rule.setTitle("LinkTo");
+ rule.setAction(linkToAction);
+ rule.setExecuteAsynchronously(false);
+ ruleService.saveRule(folder1, rule);
+
+ return null;
+ }
+ });
+
+ doTestInTransaction(new Test()
+ {
+ @Override
+ public Void run()
+ {
+ utils.createRecord(folder1, "record1" + UUID.randomUUID().toString());
+ return null;
+ }
+
+ @Override
+ public void test(Void result) throws Exception
+ {
+ assertEquals(1, nodeService.getChildAssocs(folder2).size());
+ }
+ });
+ }
+}
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/InplaceRecordPermissionTest.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/InplaceRecordPermissionTest.java
index b16c1472c3..ef086d2bc8 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/InplaceRecordPermissionTest.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/InplaceRecordPermissionTest.java
@@ -500,8 +500,7 @@ public class InplaceRecordPermissionTest extends BaseRMTestCase
* And it's metadata is maintained
* Then the inplace users will no longer see the record
*/
- // FIXME: See RM-4095
- public void ztestDestroyedRecordInplacePermissions()
+ public void testDestroyedRecordInplacePermissions()
{
test()
.given()
diff --git a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java
index acf5c1ddad..e20f77bae7 100644
--- a/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java
+++ b/rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/record/RecordTestSuite.java
@@ -38,7 +38,9 @@ import org.junit.runners.Suite.SuiteClasses;
HideInplaceRecordTest.class,
MoveInplaceRecordTest.class,
ViewRecordTest.class,
- LinkRecordTest.class
+ LinkRecordTest.class,
+ CreateInplaceRecordTest.class,
+ InplaceRecordPermissionTest.class
})
public class RecordTestSuite
{