mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge branch 'release/V2.3.0.x' into feature-2.3/RM-4162_MergeToV2.3
Conflicts: rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/CopyMoveLinkFileToBaseAction.java rm-server/source/java/org/alfresco/module/org_alfresco_module_rm/action/impl/DestroyAction.java rm-server/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/IssueTestSuite.java
This commit is contained in:
@@ -260,6 +260,7 @@
|
|||||||
<property name="capabilityService" ref="CapabilityService" />
|
<property name="capabilityService" ref="CapabilityService" />
|
||||||
<property name="recordableVersionService" ref="RecordableVersionService" />
|
<property name="recordableVersionService" ref="RecordableVersionService" />
|
||||||
<property name="eagerContentStoreCleaner" ref="eagerContentStoreCleaner"/>
|
<property name="eagerContentStoreCleaner" ref="eagerContentStoreCleaner"/>
|
||||||
|
<property name="inplaceRecordService" ref="InplaceRecordService"/>
|
||||||
<property name="ghostingEnabled">
|
<property name="ghostingEnabled">
|
||||||
<value>${rm.ghosting.enabled}</value>
|
<value>${rm.ghosting.enabled}</value>
|
||||||
</property>
|
</property>
|
||||||
@@ -761,7 +762,6 @@
|
|||||||
<property name="filePlanService" ref="FilePlanService" />
|
<property name="filePlanService" ref="FilePlanService" />
|
||||||
<property name="publicAction" value="true"/>
|
<property name="publicAction" value="true"/>
|
||||||
<property name="allowParameterSubstitutions" value="true"/>
|
<property name="allowParameterSubstitutions" value="true"/>
|
||||||
<property name="retryingTransactionHelper" ref="retryingTransactionHelper" />
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Copy To -->
|
<!-- Copy To -->
|
||||||
|
@@ -17,12 +17,10 @@ import org.alfresco.service.cmr.action.ParameterDefinition;
|
|||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
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.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,9 +33,6 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
|||||||
{
|
{
|
||||||
private static Log logger = LogFactory.getLog(CopyMoveLinkFileToBaseAction.class);
|
private static Log logger = LogFactory.getLog(CopyMoveLinkFileToBaseAction.class);
|
||||||
|
|
||||||
/** Retrying transaction helper */
|
|
||||||
private RetryingTransactionHelper retryingTransactionHelper;
|
|
||||||
|
|
||||||
/** action parameters */
|
/** action parameters */
|
||||||
public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder";
|
public static final String PARAM_DESTINATION_RECORD_FOLDER = "destinationRecordFolder";
|
||||||
public static final String PARAM_PATH = "path";
|
public static final String PARAM_PATH = "path";
|
||||||
@@ -94,14 +89,6 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
|||||||
this.filePlanService = filePlanService;
|
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)
|
* @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);
|
NodeRef recordFolder = (NodeRef)action.getParameterValue(PARAM_DESTINATION_RECORD_FOLDER);
|
||||||
if (recordFolder == null)
|
if (recordFolder == null)
|
||||||
{
|
{
|
||||||
final boolean finaltargetIsUnfiledRecords = targetIsUnfiledRecords;
|
recordFolder = createOrResolvePath(action, actionedUponNodeRef, targetIsUnfiledRecords);
|
||||||
recordFolder = retryingTransactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<NodeRef>()
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now we have the reference to the target folder we can do some final checks to see if the action is valid
|
// now we have the reference to the target folder we can do some final checks to see if the action is valid
|
||||||
@@ -170,20 +139,17 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
synchronized (this)
|
if (getMode() == CopyMoveLinkFileToActionMode.MOVE)
|
||||||
{
|
{
|
||||||
if (getMode() == CopyMoveLinkFileToActionMode.MOVE)
|
fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
|
||||||
{
|
}
|
||||||
fileFolderService.move(actionedUponNodeRef, finalRecordFolder, null);
|
else if (getMode() == CopyMoveLinkFileToActionMode.COPY)
|
||||||
}
|
{
|
||||||
else if (getMode() == CopyMoveLinkFileToActionMode.COPY)
|
fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
|
||||||
{
|
}
|
||||||
fileFolderService.copy(actionedUponNodeRef, finalRecordFolder, null);
|
else if (getMode() == CopyMoveLinkFileToActionMode.LINK)
|
||||||
}
|
{
|
||||||
else if (getMode() == CopyMoveLinkFileToActionMode.LINK)
|
getRecordService().link(actionedUponNodeRef, finalRecordFolder);
|
||||||
{
|
|
||||||
getRecordService().link(actionedUponNodeRef, finalRecordFolder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException fileNotFound)
|
catch (FileNotFoundException fileNotFound)
|
||||||
@@ -193,7 +159,6 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,23 +248,29 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
|||||||
* @param targetisUnfiledRecords true is the target is in unfiled records
|
* @param targetisUnfiledRecords true is the target is in unfiled records
|
||||||
* @return
|
* @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
|
// get the starting context
|
||||||
NodeRef context = getContext(action, actionedUponNodeRef, targetisUnfiledRecords);
|
final NodeRef context = getContext(action, actionedUponNodeRef, targetisUnfiledRecords);
|
||||||
NodeRef path = context;
|
NodeRef path = context;
|
||||||
|
|
||||||
// get the path we wish to resolve
|
// get the path we wish to resolve
|
||||||
String pathParameter = (String)action.getParameterValue(PARAM_PATH);
|
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))
|
if((pathElementsArray != null) && (pathElementsArray.length > 0))
|
||||||
{
|
{
|
||||||
// get the create parameter
|
// get the create parameter
|
||||||
Boolean createValue = (Boolean)action.getParameterValue(PARAM_CREATE_RECORD_PATH);
|
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
|
// create or resolve the specified path
|
||||||
path = createOrResolvePath(action, context, actionedUponNodeRef, Arrays.asList(pathElementsArray), targetisUnfiledRecords, create, false);
|
path = getTransactionService().getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<NodeRef>()
|
||||||
|
{
|
||||||
|
public NodeRef execute() throws Throwable
|
||||||
|
{
|
||||||
|
return createOrResolvePath(action, context, actionedUponNodeRef, Arrays.asList(pathElementsArray), targetisUnfiledRecords, create, false);
|
||||||
|
}
|
||||||
|
}, false, true);
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -388,7 +359,7 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
|||||||
NodeRef child = getChild(parent, childName);
|
NodeRef child = getChild(parent, childName);
|
||||||
if (child == null)
|
if (child == null)
|
||||||
{
|
{
|
||||||
if(targetisUnfiledRecords)
|
if (targetisUnfiledRecords)
|
||||||
{
|
{
|
||||||
// create unfiled folder
|
// create unfiled folder
|
||||||
child = fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
|
child = fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
|
||||||
|
@@ -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.capability.CapabilityService;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionActionDefinition;
|
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.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.module.org_alfresco_module_rm.version.RecordableVersionService;
|
||||||
import org.alfresco.repo.content.cleanup.EagerContentStoreCleaner;
|
import org.alfresco.repo.content.cleanup.EagerContentStoreCleaner;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
@@ -60,6 +61,9 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
|
|||||||
/** Recordable version service */
|
/** Recordable version service */
|
||||||
private RecordableVersionService recordableVersionService;
|
private RecordableVersionService recordableVersionService;
|
||||||
|
|
||||||
|
/** Inplace record service */
|
||||||
|
private InplaceRecordService inplaceRecordService;
|
||||||
|
|
||||||
/** Indicates if ghosting is enabled or not */
|
/** Indicates if ghosting is enabled or not */
|
||||||
private boolean ghostingEnabled = true;
|
private boolean ghostingEnabled = true;
|
||||||
|
|
||||||
@@ -87,6 +91,14 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
|
|||||||
this.recordableVersionService = recordableVersionService;
|
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
|
* @param ghostingEnabled true if ghosting is enabled, false otherwise
|
||||||
*/
|
*/
|
||||||
@@ -170,6 +182,9 @@ public class DestroyAction extends RMDispositionActionExecuterAbstractBase
|
|||||||
recordableVersionService.destroyRecordedVersion(version);
|
recordableVersionService.destroyRecordedVersion(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide from inplace users to give the impression of destruction
|
||||||
|
inplaceRecordService.hideRecord(record);
|
||||||
|
|
||||||
// Add the ghosted aspect
|
// Add the ghosted aspect
|
||||||
getNodeService().addAspect(record, ASPECT_GHOSTED, null);
|
getNodeService().addAspect(record, ASPECT_GHOSTED, null);
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
|||||||
RM1914Test.class,
|
RM1914Test.class,
|
||||||
//RM2190Test.class,
|
//RM2190Test.class,
|
||||||
RM2192Test.class,
|
RM2192Test.class,
|
||||||
RM3314Test.class
|
RM3314Test.class,
|
||||||
|
RM4101Test.class
|
||||||
})
|
})
|
||||||
public class IssueTestSuite
|
public class IssueTestSuite
|
||||||
{
|
{
|
||||||
|
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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<NodeRef>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public NodeRef run()
|
||||||
|
{
|
||||||
|
return filePlanService.createRecordCategory(filePlan, categoryName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final NodeRef folder1 = doTestInTransaction(new Test<NodeRef>()
|
||||||
|
{
|
||||||
|
@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<NodeRef>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public NodeRef run()
|
||||||
|
{
|
||||||
|
return recordFolderService.createRecordFolder(category1, folder2Name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
doTestInTransaction(new Test<Void>()
|
||||||
|
{
|
||||||
|
@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<Void>()
|
||||||
|
{
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -500,8 +500,7 @@ public class InplaceRecordPermissionTest extends BaseRMTestCase
|
|||||||
* And it's metadata is maintained
|
* And it's metadata is maintained
|
||||||
* Then the inplace users will no longer see the record
|
* Then the inplace users will no longer see the record
|
||||||
*/
|
*/
|
||||||
// FIXME: See RM-4095
|
public void testDestroyedRecordInplacePermissions()
|
||||||
public void ztestDestroyedRecordInplacePermissions()
|
|
||||||
{
|
{
|
||||||
test()
|
test()
|
||||||
.given()
|
.given()
|
||||||
|
@@ -38,7 +38,9 @@ import org.junit.runners.Suite.SuiteClasses;
|
|||||||
HideInplaceRecordTest.class,
|
HideInplaceRecordTest.class,
|
||||||
MoveInplaceRecordTest.class,
|
MoveInplaceRecordTest.class,
|
||||||
ViewRecordTest.class,
|
ViewRecordTest.class,
|
||||||
LinkRecordTest.class
|
LinkRecordTest.class,
|
||||||
|
CreateInplaceRecordTest.class,
|
||||||
|
InplaceRecordPermissionTest.class
|
||||||
})
|
})
|
||||||
public class RecordTestSuite
|
public class RecordTestSuite
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user