Merge branch 'master' into feature/RM-7062_NoReadOnHoldCanSeeAuditEvent

This commit is contained in:
Sara Aspery
2019-12-15 08:46:11 +00:00
100 changed files with 1351 additions and 483 deletions
+3 -3
View File
@@ -531,8 +531,8 @@
<alfresco.db.username>alfresco</alfresco.db.username>
<alfresco.groupId>org.alfresco</alfresco.groupId>
<alfresco.share.artifactId>share</alfresco.share.artifactId>
<alfresco-spring-webscripts.version>7.8</alfresco-spring-webscripts.version>
<api.explorer.version>6.1.0</api.explorer.version>
<alfresco-spring-webscripts.version>7.9</alfresco-spring-webscripts.version>
<api.explorer.version>6.2.0</api.explorer.version>
<!-- Set this here and override it in the community and enterprise modules. -->
<alfresco.version>0.0</alfresco.version>
@@ -559,7 +559,7 @@
<maven.tomcat.port>8080</maven.tomcat.port>
<jackson.version>2.9.9</jackson.version>
<jackson-databind.version>2.9.9.3</jackson-databind.version>
<jackson-databind.version>2.9.10</jackson-databind.version>
<fabric8.docker.version>0.31.0</fabric8.docker.version>
<mockito.version>1.10.19</mockito.version>
<postgresql.version>42.2.6</postgresql.version>
@@ -34,6 +34,11 @@ package org.alfresco.rest.rm.community.model.fileplancomponents;
*/
public class FilePlanComponentAspects
{
/** Private constructor to prevent instantiation. */
private FilePlanComponentAspects()
{
}
// aspect present on completed records
public static final String ASPECTS_COMPLETED_RECORD = "rma:declaredRecord";
@@ -42,4 +47,10 @@ public class FilePlanComponentAspects
// aspect present on vital records
public static final String ASPECTS_VITAL_RECORD = "rma:vitalRecord";
// Frozen aspect
public static final String FROZEN_ASPECT = "rma:frozen";
// recordSearch aspect
public static final String RECORD_SEARCH_ASPECT = "rma:recordSearch";
}
@@ -32,6 +32,7 @@ import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.ADD_TO_HOLD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH;
import static org.alfresco.utility.Utility.buildPath;
import static org.alfresco.utility.Utility.removeLastSlash;
import static org.alfresco.utility.data.RandomData.getRandomName;
@@ -129,14 +130,13 @@ public class AuditAddToHoldTests extends BaseRMRestTest
@DataProvider (name = "validNodesForAddToHold")
public Object[][] getValidNodesForAddToHold() throws Exception
{
String documentLibrary = "/documentLibrary";
FileModel contentToBeAdded = dataContent.usingAdmin().usingSite(privateSite)
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
RecordCategoryChild recordFolderToBeAdded = createRecordFolder(recordCategory.getId(), PREFIX + "recFolderToBeAdded");
Record recordToBeAdded = createElectronicRecord(recordFolder.getId(), PREFIX + "record");
String recordFolderPath = removeLastSlash(buildPath(documentLibrary, recordCategory.getName(),
String recordFolderPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
recordFolderToBeAdded.getName()));
String recordPath = removeLastSlash(buildPath(documentLibrary, recordCategory.getName(),
String recordPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
recordFolder.getName(), recordToBeAdded.getName()));
String contentPath = "/Company Home" + contentToBeAdded.getCmisLocation();
@@ -32,6 +32,7 @@ import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.audit.AuditEvents.REMOVE_FROM_HOLD;
import static org.alfresco.rest.rm.community.util.CommonTestUtils.generateTestPrefix;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.FILE_PLAN_PATH;
import static org.alfresco.utility.Utility.buildPath;
import static org.alfresco.utility.Utility.removeLastSlash;
import static org.alfresco.utility.data.RandomData.getRandomName;
@@ -144,10 +145,9 @@ public class AuditRemoveFromHoldTests extends BaseRMRestTest
@DataProvider (name = "validNodesForRemoveFromHold")
public Object[][] getValidNodesForRemoveFromHold()
{
String documentLibrary = "/documentLibrary";
String recordFolderPath = removeLastSlash(buildPath(documentLibrary, recordCategory.getName(),
String recordFolderPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
heldRecordFolder.getName()));
String recordPath = removeLastSlash(buildPath(documentLibrary, recordCategory.getName(),
String recordPath = removeLastSlash(buildPath(FILE_PLAN_PATH, recordCategory.getName(),
recordFolder.getName(), heldRecord.getName()));
String contentPath = "/Company Home" + heldContent.getCmisLocation();
@@ -818,7 +818,7 @@ public class BaseRMRestTest extends RestTest
*/
protected boolean hasAspect(String nodeId, String aspectName) throws Exception
{
return hasAspect(toFileModel(nodeId),aspectName);
return hasAspect(toFileModel(nodeId), aspectName);
}
/**
@@ -107,9 +107,4 @@ public interface TestData
* The default hold reason
*/
String HOLD_REASON = "Active content to be reviewed for the CASE McDermott, FINRA ";
/**
* Frozen aspect
*/
String FROZEN_ASPECT = "rma:frozen";
}
@@ -26,12 +26,13 @@
*/
package org.alfresco.rest.rm.community.hold;
import static org.alfresco.rest.rm.community.base.TestData.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
@@ -28,9 +28,9 @@ package org.alfresco.rest.rm.community.hold;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.TestData.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_DESCRIPTION;
import static org.alfresco.rest.rm.community.base.TestData.HOLD_REASON;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.FROZEN_ASPECT;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_MANAGER;
@@ -31,6 +31,7 @@ import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.RECORD_SEARCH_ASPECT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.NON_ELECTRONIC_RECORD_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
@@ -41,7 +42,7 @@ import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.Assert.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.record.Record;
@@ -50,10 +51,11 @@ import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.report.Bug;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -67,19 +69,35 @@ import org.testng.annotations.Test;
public class FileRecordsTests extends BaseRMRestTest
{
private UnfiledContainerChild electronicRecord = UnfiledContainerChild.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
private UnfiledContainerChild nonelectronicRecord = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
.properties(UnfiledContainerChildProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
private String targetFolderId, folderToLink, closedFolderId, unfiledRecordFolderId;
@BeforeClass (alwaysRun = true)
public void setupFileRecordsTests() throws Exception
{
// create 3 record folders and close one of them
targetFolderId = createCategoryFolderInFilePlan().getId();
folderToLink = createCategoryFolderInFilePlan().getId();
closedFolderId = createCategoryFolderInFilePlan().getId();
closeFolder(closedFolderId);
// create one unfiled record folder
unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS,
"Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
}
/**
* Invalid containers where electronic and non-electronic records can be filed
@@ -98,66 +116,63 @@ public class FileRecordsTests extends BaseRMRestTest
};
}
/**
* Returns the ids of unfiled electronic and non-electronic records from Unfiled Records container
*/
@DataProvider (name = "unfiledRecordsFromUnfiledRecordsContainer")
public Object[][] getRecordsFromUnfiledRecordsContainer()
{
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord,
UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
return new String[][] {
{ recordElectronic.getId()},
{ recordNonElect.getId()}
};
}
/**
* Returns the ids of unfiled electronic and non-electronic records from an Unfiled Record Folder
*/
@DataProvider (name = "unfiledRecordsFromUnfiledRecordFolder")
public Object[][] getRecordsFromUnfiledRecordFolder()
{
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild recordElectronic = unfiledRecordFoldersAPI.uploadRecord(electronicRecord, unfiledRecordFolderId,
createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, unfiledRecordFolderId);
return new String[][] {
{ recordElectronic.getId()},
{ recordNonElect.getId()}
};
}
/**
* Given an unfiled record in the root unfiled record container
* And an open record folder
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@Test
public void fileRecordIntoExistingFolderFromUnfiledContainer() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
@AlfrescoTest (jira = "RM-7060")
public void fileRecordFromUnfiledContainerToOpenFolder(String unfiledRecordId) throws Exception
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS,
createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the record to the folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(),folderId);
assertEquals(recordFiled.getParentId(), targetFolderId);
// check the record is filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record is filed to the record folder
assertTrue(isRecordChildOfRecordFolder(unfiledRecordId, targetFolderId), unfiledRecordId + " is not filed to " + targetFolderId);
// check the record doesn't exist into unfiled record container
assertFalse(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
Record nonElectRecordFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(nonElectRecordFiled.getParentId(), folderId);
// check the record is added into the record folder
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
assertFalse(isRecordChildOfUnfiledContainer(unfiledRecordId), unfiledRecordId + " exists in Unfiled Records");
assertTrue(hasAspect(unfiledRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after filing!");
}
/**
@@ -166,62 +181,24 @@ public class FileRecordsTests extends BaseRMRestTest
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@Test
public void fileRecordIntoExistingFolderFromUnfiledRecordFolder() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordFolder")
@AlfrescoTest (jira = "RM-7060")
public void fileRecordFromUnfiledRecordFolderToOpenFolder(String unfiledRecordId) throws Exception
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
// create records
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
String unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
UnfiledContainerChild recordElectronic = unfiledRecordFoldersAPI.uploadRecord(electronicRecord, unfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, unfiledRecordFolderId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the record to the folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(),folderId);
assertEquals(recordFiled.getParentId(), targetFolderId);
// check the record is filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record is filed to the record folder
assertTrue(isRecordChildOfRecordFolder(unfiledRecordId, targetFolderId), unfiledRecordId + " is not filed to " + targetFolderId);
// check the record doesn't exist into unfiled record folder
assertFalse(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
Record nonElectRecordFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(nonElectRecordFiled.getParentId(), folderId);
// check the record is added into the record folder
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record doesn't exist into unfiled record folder
assertFalse(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
assertFalse(isRecordChildOfUnfiledRecordFolder(unfiledRecordId),
unfiledRecordId + " exists in " + unfiledRecordFolderId);
assertTrue(hasAspect(unfiledRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after filing!");
}
/**
@@ -231,55 +208,19 @@ public class FileRecordsTests extends BaseRMRestTest
* Then I get an unsupported operation exception
*
*/
@Test
public void fileRecordIntoCloseFolderFromUnfiledContainer() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
public void fileRecordFromUnfiledContainerToClosedFolder(String unfiledRecordId)
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
closeFolder(folderId);
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the record to the closed record folder
fileRecordToFolder(unfiledRecordId, closedFolderId);
// check the response status
assertStatusCode(FORBIDDEN);
// check the record is not filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record is not filed to the record folder
assertFalse(isRecordChildOfRecordFolder(unfiledRecordId, closedFolderId), unfiledRecordId + " is filed to " + closedFolderId);
// check the record exist into unfiled record container
assertTrue(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(FORBIDDEN);
// check the record is not added into the record folder
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record exist into unfiled record container
assertTrue(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
assertTrue(isRecordChildOfUnfiledContainer(unfiledRecordId), unfiledRecordId + " doesn't exist in Unfiled Records");
}
/**
@@ -289,56 +230,20 @@ public class FileRecordsTests extends BaseRMRestTest
* Then I get an unsupported operation exception
*
*/
@Test
public void fileRecordIntoCloseFolderFromUnfiledRecordFolder() throws Exception
@Test(dataProvider = "unfiledRecordsFromUnfiledRecordFolder")
public void fileRecordFromUnfiledRecordFolderToClosedFolder(String unfiledRecordId)
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
closeFolder(folderId);
// create records
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
String unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
UnfiledContainerChild recordElectronic = unfiledRecordFoldersAPI.uploadRecord(electronicRecord, unfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, unfiledRecordFolderId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(folderId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the record into the closed folder created
fileRecordToFolder(unfiledRecordId, closedFolderId);
// check the response status
assertStatusCode(FORBIDDEN);
// check the record is not filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
assertFalse(isRecordChildOfRecordFolder(unfiledRecordId, closedFolderId), unfiledRecordId + " is filed to " + closedFolderId);
// check the record exist into unfiled record folder
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(FORBIDDEN);
// check the record is not added into the record folder
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record exist into unfiled record folder
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
assertTrue(isRecordChildOfUnfiledRecordFolder(unfiledRecordId),
unfiledRecordId + " doesn't exist in " + unfiledRecordFolderId);
}
/**
@@ -347,71 +252,34 @@ public class FileRecordsTests extends BaseRMRestTest
* When I file the filed record into the record folder
* Then the record is filed in both locations
*/
@Test
@Bug(id="RM-4578")
public void linkRecordInto() throws Exception
@Test (dataProvider = "unfiledRecordsFromUnfiledRecordsContainer")
@Bug (id = "RM-4578")
public void linkRecordInto(String unfiledRecordId)
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String parentFolderId = createCategoryFolderInFilePlan().getId();
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(parentFolderId).build();
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
Record nonElectronicFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// file the record to the open folder created
Record recordFiled = fileRecordToFolder(unfiledRecordId, targetFolderId);
// check the response status
assertStatusCode(CREATED);
// create the second folder
String folderToLink = createCategoryFolderInFilePlan().getId();
recordBodyFile = RecordBodyFile.builder().targetParentId(folderToLink).build();
// check the response status
// link the record to the second folder
Record recordLink = fileRecordToFolder(unfiledRecordId, folderToLink);
assertStatusCode(CREATED);
// link the electronic record
Record recordLink = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
assertTrue(recordLink.getParentId().equals(parentFolderId));
// check the response status code
assertStatusCode(CREATED);
// link the nonelectronic record
Record nonElectronicLink = recordsAPI.fileRecord(recordBodyFile, nonElectronicFiled.getId());
assertStatusCode(CREATED);
assertTrue(nonElectronicLink.getParentId().equals(parentFolderId));
assertTrue(recordLink.getParentId().equals(targetFolderId));
// check the record is added into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(parentFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId)));
assertTrue(recordFolderAPI.getRecordFolderChildren(targetFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(targetFolderId)));
// check the record doesn't exist into unfiled record container
// check the record has a link in the second folder
assertTrue(recordFolderAPI.getRecordFolderChildren(folderToLink)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
// check the record is added into the record folder
assertTrue(recordFolderAPI.getRecordFolderChildren(parentFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(nonElectronicFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId)));
// check the record doesn't exist into unfiled record container
assertTrue(recordFolderAPI.getRecordFolderChildren(folderToLink)
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(nonElectronicFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
.getEntries().stream()
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(targetFolderId) &&
!c.getEntry().getParentId().equals(folderToLink)));
}
/**
@@ -425,24 +293,77 @@ public class FileRecordsTests extends BaseRMRestTest
dataProvider = "invalidContainersToFile",
description = "File the unfiled record to the container that is not a record folder"
)
public void invalidContainerToFile(String containerId) throws Exception
public void invalidContainerToFile(String containerId)
{
// get API instances
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create records
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordElectronic = unfiledContainersAPI.uploadRecord(electronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
UnfiledContainerChild recordNonElect = unfiledContainersAPI.createUnfiledContainerChild(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(containerId).build();
recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// file the records to a container that is not a record folder
fileRecordToFolder(recordElectronic.getId(), containerId);
assertStatusCode(BAD_REQUEST);
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status
fileRecordToFolder(recordNonElect.getId(), containerId);
assertStatusCode(BAD_REQUEST);
}
/**
* Files the given record in the target record folder.
*
* @param recordId the id of the record to be filed
* @param targetFolderId the id of the target record folder
*/
private Record fileRecordToFolder(String recordId, String targetFolderId)
{
RecordBodyFile recordBodyFile = RecordBodyFile.builder().targetParentId(targetFolderId).build();
return getRestAPIFactory().getRecordsAPI().fileRecord(recordBodyFile, recordId);
}
/**
* Returns whether any child of the record folder match the provided record
*
* @param recordId the record id
* @param recordFolderId the record folder id
* @return true if any child of the record folder match the provided record, false otherwise
*/
private boolean isRecordChildOfRecordFolder(String recordId, String recordFolderId)
{
return getRestAPIFactory().getRecordFolderAPI()
.getRecordFolderChildren(recordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordId));
}
/**
* Returns whether any child of the unfiled record folder match the provided record
*
* @param recordId the record id
* @return true if any child of the unfiled record folder match the provided record, false otherwise
*/
private boolean isRecordChildOfUnfiledRecordFolder(String recordId)
{
return getRestAPIFactory().getUnfiledRecordFoldersAPI()
.getUnfiledRecordFolderChildren(unfiledRecordFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordId));
}
/**
* Returns whether any child of the unfiled container match the provided record
*
* @param recordId the record id
* @return true if any child of the unfiled container match the provided record, false otherwise
*/
private boolean isRecordChildOfUnfiledContainer(String recordId)
{
return getRestAPIFactory().getUnfiledContainersAPI()
.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordId));
}
}
@@ -0,0 +1,63 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2019 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* 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/>.
* #L%
*/
package org.alfresco.rest.rm.community.records;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.RECORD_SEARCH_ASPECT;
import static org.alfresco.rest.rm.community.utils.CoreUtil.createBodyForMoveCopy;
import static org.alfresco.rest.rm.community.utils.CoreUtil.toContentModel;
import static org.alfresco.utility.report.log.Step.STEP;
import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.test.AlfrescoTest;
import org.testng.annotations.Test;
/**
* Move records tests
*
* @author Claudia Agache
* @since 3.3
*/
public class MoveRecordsTests extends BaseRMRestTest
{
@Test (description = "rma:recordSearch aspect is reapplied after record move")
@AlfrescoTest (jira = "RM-7060")
public void moveRecord() throws Exception
{
String parentFolderId = createCategoryFolderInFilePlan().getId();
String targetFolderId = createCategoryFolderInFilePlan().getId();
String electronicRecordId = createElectronicRecord(parentFolderId, ELECTRONIC_RECORD_NAME).getId();
STEP("Move record from one folder to the other");
getRestAPIFactory().getNodeAPI(toContentModel(electronicRecordId)).move(createBodyForMoveCopy(targetFolderId));
assertStatusCode(OK);
STEP("Check the record still has rma:recordSearch aspect.");
assertTrue(hasAspect(electronicRecordId, RECORD_SEARCH_ASPECT), "recordSearch aspect is lost after move!");
}
}
@@ -49,6 +49,7 @@ public class RMSiteUtil
public static final String RM_ID = "rm";
public static final String RM_TITLE = "Records Management";
public static final String RM_DESCRIPTION = "Records Management Site";
public static final String FILE_PLAN_PATH = "/rm/documentLibrary";
/**
* Creates an RM Site model for the given compliance, title and description
+2 -2
View File
@@ -75,8 +75,8 @@
<properties>
<spring.version>5.1.8.RELEASE</spring.version>
<alfresco.version>6.1.2-ga</alfresco.version>
<share.version>6.1.0</share.version>
<alfresco.version>6.2.0-ga</alfresco.version>
<share.version>6.2.0</share.version>
<!-- The properties app.amp.* need to be set for share to work. -->
<app.filtering.enabled>true</app.filtering.enabled>
</properties>
+6 -3
View File
@@ -1,3 +1,6 @@
SOLR6_TAG=1.1.1
POSTGRES_TAG=10.1
ACTIVEMQ_TAG=5.15.6
TRANSFORMERS_TAG=2.1.0
SOLR6_TAG=1.4.0
POSTGRES_TAG=11.4
ACTIVEMQ_TAG=5.15.8
LEGACY_TRANSFORM_SERVICE_ENABLED=true
LOCAL_TRANSFORM_SERVICE_ENABLED=true
+16 -2
View File
@@ -1,4 +1,9 @@
FROM alfresco/alfresco-content-repository-community:6.1.2-ga
### Apply AGS community repo AMP to ACS image
FROM alfresco/alfresco-content-repository-community:6.2.0-ga
# Alfresco user does not have permissions to modify webapps or configuration. Switch to root.
# The access will be fixed after all operations are done.
USER root
COPY target/alfresco-governance-services-community-repo-*.amp /usr/local/tomcat/amps/
@@ -10,4 +15,13 @@ COPY target/gs-api-explorer-*.war /usr/local/tomcat/webapps/
### Unpack gs-api-explorer.war
RUN mkdir /usr/local/tomcat/webapps/gs-api-explorer && cd /usr/local/tomcat/webapps/gs-api-explorer && \
jar -xvf /usr/local/tomcat/webapps/gs-api-explorer-*.war && rm -f /usr/local/tomcat/webapps/gs-api-explorer-*.war
jar -xvf /usr/local/tomcat/webapps/gs-api-explorer-*.war && rm -f /usr/local/tomcat/webapps/gs-api-explorer-*.war
# All files in the tomcat folder must be owned by root user and Alfresco group as mentioned in the parent Dockerfile
RUN chgrp -R Alfresco /usr/local/tomcat && \
find /usr/local/tomcat/webapps -type d -exec chmod 0750 {} \; && \
find /usr/local/tomcat/webapps -type f -exec chmod 0640 {} \; && \
chmod -R g+r /usr/local/tomcat/webapps
# Switching back to alfresco user after having added amps files to run the container as non-root
USER alfresco
@@ -732,6 +732,10 @@
<title>Saved search</title>
</aspect>
<aspect name="rma:dispositionProcessed">
<title>Disposition processed</title>
</aspect>
<aspect name="rma:vitalRecordDefinition">
<title>Vital Record Definition</title>
<properties>
@@ -16,5 +16,5 @@
<property name="filePlanService" ref="filePlanService"/>
<property name="nodeService" ref="nodeService"/>
</bean>
</beans>
@@ -3,16 +3,30 @@
<mapper namespace="alfresco.query.rm">
<parameterMap id="parameter_CountRMIndentifier" type="map">
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
</parameterMap>
<parameterMap id="parameter_CountRMIndentifier" type="map">
<parameter property="qnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="idValue" jdbcType="BIGINT" javaType="java.lang.String"/>
</parameterMap>
<resultMap id="result_NodeIds" type="java.lang.Long">
<result property="node.id" column="node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
<parameterMap id="parameter_folderPatchPaging" type="map">
<parameter property="processed" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="folderQnameId" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="start" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="end" jdbcType="BIGINT" javaType="java.lang.Long"/>
</parameterMap>
<resultMap id="result_NodeRefEntity" type="org.alfresco.module.org_alfresco_module_rm.query.NodeRefEntity">
<result property="row" column="row" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="protocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="identifier" column="identifier" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="uuid" column="uuid" jdbcType="VARCHAR" javaType="java.lang.String"/>
</resultMap>
<resultMap id="result_NodeIds" type="java.lang.Long">
<result property="node.id" column="node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<select id="select_CountRMIndentifier" parameterMap="parameter_CountRMIndentifier" resultType="java.lang.Integer">
select
count(*)
from
@@ -21,7 +35,7 @@
where
prop.qname_id = ? and
prop.string_value = ?
</select>
<!-- Get distinct property values of children for a given property qname -->
@@ -39,10 +53,10 @@
</select>
<!-- Get list of node ids which reference given content url -->
<select id="select_NodeIdsWhichReferenceContentUrl"
parameterType="ContentUrl"
resultMap="result_NodeIds">
<!-- Get list of node ids which reference given content url -->
<select id="select_NodeIdsWhichReferenceContentUrl"
parameterType="ContentUrl"
resultMap="result_NodeIds">
select
p.node_id
from
@@ -55,5 +69,19 @@
</select>
<select id="select_RecordFoldersWithSchedules"
parameterMap="parameter_folderPatchPaging"
resultMap="result_NodeRefEntity">
select alfn.id , alfs.protocol, alfs.identifier, alfn.uuid
from alf_node alfn, alf_store alfs
where alfn.id not in (
select node_id
from alf_node_aspects
where qname_id = ? )
and type_qname_id = ?
and alfn.store_id = alfs.id
and alfn.id between ? and ?
</select>
</mapper>
</mapper>
@@ -680,4 +680,21 @@
parent="rmBaseWebscript">
<property name="relationshipService" ref="RelationshipService" />
</bean>
<!-- Update record schedule GET webscript -->
<bean id="webscript.org.alfresco.repository.schedules.rm-updaterecordschedule.get"
class="org.alfresco.repo.web.scripts.schedule.UpdateRecordScheduleGet"
parent="webscript">
<property name="nodeDAO" ref="nodeDAO"/>
<property name="qnameDAO" ref="qnameDAO"/>
<property name="nodeService" ref="nodeService"/>
<property name="transactionService" ref="transactionService"/>
<property name="dispositionService" ref="dispositionService"/>
<property name="recordService" ref="recordService"/>
<property name="recordsManagementQueryDAO" ref="recordsManagementQueryDAO"/>
<property name="behaviourFilter" ref="policyBehaviourFilter" />
<property name="frozenAspect" ref="rma.freeze"/>
<property name="recordsManagementSearchBehaviour" ref="recordsManagementSearchBehaviour"/>
</bean>
</beans>
@@ -38,7 +38,7 @@ rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildByName
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getChildrenByName=RM.Read.0,AFTER_RM.FilterNode
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getPrimaryParent=RM.Read.0
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.createAssociation=RM.Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAssociation=Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.removeAssociation=RM.Assoc.0.1
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getTargetAssocs=RM.Read.0
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getSourceAssocs=RM.Read.0
rm.methodsecurity.org.alfresco.service.cmr.repository.NodeService.getAssoc=RM.Read.0
@@ -0,0 +1,13 @@
<webscript>
<shortname>Updates Record Schedules based on Hierarchical Retention Instructions</shortname>
<description><![CDATA[
Updates records schedules by reviewing retention instructions defined within the principle hierarchy.<br/>
URL parameter maxRecordFolders is optional, and represents the maximum number of record folders that should be processed. If not specified maxRecordFolders will be set to the max value for an integer.<br/>
URL parameter recordFolder is optional, and represents the nodeRef of a record folder whose records should be processed. If specified then maxRecordFolders will be ignored.<br/>
]]>
</description>
<url>/api/rm/rm-updateRecordSchedule?maxRecordFolders={maxRecordFolders?}&amp;recordFolder={recordFolder?}</url>
<format default="json">argument</format>
<authentication>admin</authentication>
<transaction allow="readonly">required</transaction>
</webscript>
@@ -0,0 +1,30 @@
<#--
#%L
Alfresco Records Management Module
%%
Copyright (C) 2005 - 2019 Alfresco Software Limited
%%
This file is part of the Alfresco software.
-
If the software was purchased under a paid Alfresco license, the terms of
the paid license agreement will prevail. Otherwise, the software is
provided under the following open source license terms:
-
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/>.
#L%
-->
{
"responsestatus" : "${responsestatus?json_string}",
"message" : "${message?json_string}"
}
@@ -22,21 +22,71 @@ services:
-Dindex.subsystem.name=solr6
-Dalfresco.restApi.basicAuthScheme=true
-Dimap.server.enabled=true
-Dimap.server.port=1143
-Dftp.enabled=true
-Dftp.port=1221
-Dftp.dataPortFrom=30000
-Dftp.dataPortTo=30099
-Dshare.host=localhost
-Daos.baseUrlOverwrite=http://localhost:8080/alfresco/aos
-Dmessaging.broker.url=\"failover:(tcp://activemq:61616)?timeout=3000&jms.useCompression=true\"
-Dlocal.transform.service.enabled=${LOCAL_TRANSFORM_SERVICE_ENABLED}
-DlocalTransform.pdfrenderer.url=http://alfresco-pdf-renderer:8090/
-DlocalTransform.imagemagick.url=http://imagemagick:8090/
-DlocalTransform.libreoffice.url=http://libreoffice:8090/
-DlocalTransform.tika.url=http://tika:8090/
-DlocalTransform.misc.url=http://transform-misc:8090/
-Dlegacy.transform.service.enabled=${LEGACY_TRANSFORM_SERVICE_ENABLED}
-Dalfresco-pdf-renderer.url=http://alfresco-pdf-renderer:8090/
-Djodconverter.url=http://libreoffice:8090/
-Dimg.url=http://imagemagick:8090/
-Dtika.url=http://tika:8090/
-Dtransform.misc.url=http://transform-misc:8090/
"
ports:
- 8080:8080
- 8000:8000
- 445:445
- 143:143
- "21:21"
- 1143:1143
- "21:1221"
- "30000-30099:30000-30099"
alfresco-pdf-renderer:
image: alfresco/alfresco-pdf-renderer:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8090:8090
imagemagick:
image: alfresco/alfresco-imagemagick:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8091:8090
libreoffice:
image: alfresco/alfresco-libreoffice:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8092:8090
tika:
image: alfresco/alfresco-tika:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8093:8090
transform-misc:
image: alfresco/alfresco-transform-misc:${TRANSFORMERS_TAG}
environment:
JAVA_OPTS: " -Xms256m -Xmx256m"
ports:
- 8094:8090
postgres:
image: library/postgres:${POSTGRES_TAG}
environment:
@@ -57,6 +107,8 @@ services:
- SOLR_SOLR_PORT=8983
#Create the default alfresco and archive cores
- SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
#HTTP by default
- ALFRESCO_SECURE_COMMS=none
ports:
- 8083:8983 #Browser port
+5 -5
View File
@@ -24,11 +24,11 @@
<alfresco.repo.artifactId>alfresco-platform</alfresco.repo.artifactId>
<alfresco.postgres.version>9.1-901.jdbc4</alfresco.postgres.version>
<ags.artifactId>alfresco-governance-services-community-repo</ags.artifactId>
<!-- 6.1.2-ga changes -->
<dependency.alfresco-core.version>7.5.1</dependency.alfresco-core.version>
<dependency.alfresco-repository.version>7.33.12</dependency.alfresco-repository.version>
<dependency.alfresco-remote-api.version>7.34.1</dependency.alfresco-remote-api.version>
<alfresco.alfresco-share-services.version>6.1.0</alfresco.alfresco-share-services.version>
<!-- 6.2.0-ga changes -->
<dependency.alfresco-core.version>7.22</dependency.alfresco-core.version>
<dependency.alfresco-repository.version>7.134.1</dependency.alfresco-repository.version>
<dependency.alfresco-remote-api.version>7.107.1</dependency.alfresco-remote-api.version>
<alfresco.alfresco-share-services.version>6.2.0</alfresco.alfresco-share-services.version>
<image.name>alfresco/alfresco-governance-repository-community</image.name>
<maven.javadoc.skip>false</maven.javadoc.skip>
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.caveat;
import static org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace;
import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;
import java.io.File;
import java.io.InputStream;
@@ -44,6 +44,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import net.sf.acegisecurity.AccessDeniedException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.caveat.RMListOfValuesConstraint.MatchLogic;
@@ -81,8 +82,6 @@ import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import net.sf.acegisecurity.AccessDeniedException;
/**
* RM Caveat Config component impl
*
@@ -1042,7 +1041,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
sb.append("' to the JSONObject 'listMembers' '");
sb.append(listMembers);
sb.append("': ");
sb.append(getFullStackTrace(error));
sb.append(getStackTrace(error));
throw new AlfrescoRuntimeException(sb.toString());
}
}
@@ -1061,7 +1060,7 @@ public class RMCaveatConfigComponentImpl implements ContentServicePolicies.OnCon
sb.append("' to the JSONObject 'configJSONObject' '");
sb.append(configJSONObject);
sb.append("': ");
sb.append(getFullStackTrace(error));
sb.append(getStackTrace(error));
throw new AlfrescoRuntimeException(sb.toString());
}
}
@@ -39,7 +39,7 @@ import org.alfresco.service.cmr.dictionary.ConstraintException;
import org.alfresco.service.cmr.i18n.MessageLookup;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -36,7 +36,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.service.cmr.security.AuthorityService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.action;
import static org.apache.commons.lang.StringUtils.leftPad;
import static org.apache.commons.lang3.StringUtils.leftPad;
import java.io.Serializable;
import java.util.HashSet;
@@ -683,7 +683,7 @@ public abstract class RMActionExecuterAbstractBase extends PropertySubActionExe
*
* @return padded string or the original if already at &gt;= len characters
*
* @deprecated As of 2.1, replaced by {@link org.apache.commons.lang.StringUtils#leftPad(String, int)}
* @deprecated As of 2.1, replaced by {@link org.apache.commons.lang3.StringUtils#leftPad(String, int)}
*/
@Deprecated
protected String padString(String s, int len)
@@ -37,7 +37,7 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,7 +43,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Destroy action.
@@ -31,7 +31,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.module.org_alfresco_module_rm.action.RMActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -42,7 +42,7 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -45,7 +45,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.namespace.QName;
import org.alfresco.workflow.RMWorkflowModel;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.action.impl;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.IOException;
import java.io.InputStream;
@@ -33,6 +33,7 @@ import static org.alfresco.model.ContentModel.PROP_USERNAME;
import static org.alfresco.module.org_alfresco_module_rm.audit.event.UserGroupMembershipUtils.PARENT_GROUP;
import static org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model.TYPE_DOD_5015_SITE;
import static org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType.DEFAULT_SITE_NAME;
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.io.BufferedWriter;
@@ -95,8 +96,7 @@ import org.alfresco.util.PropertyCheck;
import org.alfresco.util.PropertyMap;
import org.alfresco.util.TempFileProvider;
import org.alfresco.util.transaction.TransactionListenerAdapter;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
@@ -140,6 +140,7 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
protected static final String RM_AUDIT_SNIPPET_CHANGES = "/changes";
protected static final String RM_AUDIT_SNIPPET_BEFORE = "/before";
protected static final String RM_AUDIT_SNIPPET_AFTER = "/after";
protected static final String RM_AUDIT_SITES_PATH = "/Sites";
protected static final String RM_AUDIT_DATA_PERSON_FULLNAME = "/RM/event/person/fullName";
protected static final String RM_AUDIT_DATA_PERSON_ROLES = "/RM/event/person/roles";
@@ -1159,29 +1160,29 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
writer.write("<span class=\"label\">From:</span>");
writer.write("<span class=\"value\">");
Date from = params.getDateFrom();
writer.write(from == null ? "&lt;Not Set&gt;" : StringEscapeUtils.escapeHtml(from.toString()));
writer.write(from == null ? "&lt;Not Set&gt;" : escapeHtml4(from.toString()));
writer.write("</span>");
writer.write("<span class=\"label\">To:</span>");
writer.write("<span class=\"value\">");
Date to = params.getDateTo();
writer.write(to == null ? "&lt;Not Set&gt;" : StringEscapeUtils.escapeHtml(to.toString()));
writer.write(to == null ? "&lt;Not Set&gt;" : escapeHtml4(to.toString()));
writer.write("</span>");
writer.write("<span class=\"label\">Property:</span>");
writer.write("<span class=\"value\">");
QName prop = params.getProperty();
writer.write(prop == null ? "All" : StringEscapeUtils.escapeHtml(getPropertyLabel(prop)));
writer.write(prop == null ? "All" : escapeHtml4(getPropertyLabel(prop)));
writer.write("</span>");
writer.write("<span class=\"label\">User:</span>");
writer.write("<span class=\"value\">");
writer.write(params.getUser() == null ? "All" : StringEscapeUtils.escapeHtml(params.getUser()));
writer.write(params.getUser() == null ? "All" : escapeHtml4(params.getUser()));
writer.write("</span>");
writer.write("<span class=\"label\">Event:</span>");
writer.write("<span class=\"value\">");
writer.write(params.getEvent() == null ? "All" : StringEscapeUtils.escapeHtml(getAuditEventLabel(params.getEvent())));
writer.write(params.getEvent() == null ? "All" : escapeHtml4(getAuditEventLabel(params.getEvent())));
writer.write("</span>\n");
writer.write("</div>\n");
@@ -1223,26 +1224,26 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
writer.write("<div class=\"audit-entry-header\">");
writer.write("<span class=\"label\">Timestamp:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(entry.getTimestamp().toString()));
writer.write(escapeHtml4(entry.getTimestamp().toString()));
writer.write("</span>");
writer.write("<span class=\"label\">User:</span>");
writer.write("<span class=\"value\">");
writer.write(entry.getFullName() != null ?
StringEscapeUtils.escapeHtml(entry.getFullName()) :
StringEscapeUtils.escapeHtml(entry.getUserName()));
escapeHtml4(entry.getFullName()) :
escapeHtml4(entry.getUserName()));
writer.write("</span>");
if (entry.getUserRole() != null && entry.getUserRole().length() > 0)
{
writer.write("<span class=\"label\">Role:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(entry.getUserRole()));
writer.write(escapeHtml4(entry.getUserRole()));
writer.write("</span>");
}
if (entry.getEvent() != null && entry.getEvent().length() > 0)
{
writer.write("<span class=\"label\">Event:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(getAuditEventLabel(entry.getEvent())));
writer.write(escapeHtml4(getAuditEventLabel(entry.getEvent())));
writer.write("</span>\n");
}
writer.write("</div>\n");
@@ -1251,35 +1252,39 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
{
writer.write("<span class=\"label\">Identifier:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(entry.getIdentifier()));
writer.write(escapeHtml4(entry.getIdentifier()));
writer.write("</span>");
}
if (entry.getNodeType() != null && entry.getNodeType().length() > 0)
{
writer.write("<span class=\"label\">Type:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(entry.getNodeType()));
writer.write(escapeHtml4(entry.getNodeType()));
writer.write("</span>");
}
if (entry.getPath() != null && entry.getPath().length() > 0)
{
// we need to strip off the first part of the path
String path = entry.getPath();
String displayPath = path;
int idx = path.indexOf('/', 1);
String displayPath;
int idx = path.indexOf(RM_AUDIT_SITES_PATH);
if (idx != -1)
{
displayPath = "/File Plan" + path.substring(idx);
displayPath = path.substring(idx + RM_AUDIT_SITES_PATH.length());
}
else
{
displayPath = path;
}
writer.write("<span class=\"label\">Location:</span>");
writer.write("<span class=\"value\">");
writer.write(StringEscapeUtils.escapeHtml(displayPath));
writer.write(escapeHtml4(displayPath));
writer.write("</span>");
}
writer.write("</div>\n");
if (entry.getChangedProperties() != null)
if (entry.getChangedProperties() != null && !entry.getChangedProperties().isEmpty())
{
writer.write("<table class=\"changed-values-table\" cellspacing=\"0\">");
writer.write("<tr><th>Property</th><th>Previous Value</th><th>New Value</th></tr>");
@@ -1302,17 +1307,17 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
if(DataTypeDefinition.MLTEXT.equals(propDataType))
{
writer.write(values.getFirst() == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(convertToMlText((Map)values.getFirst()).getDefaultValue()));
writer.write(values.getFirst() == null ? "&lt;none&gt;" : escapeHtml4(convertToMlText((Map) values.getFirst()).getDefaultValue()));
writer.write("</td><td>");
writer.write(values.getSecond() == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(convertToMlText((Map)values.getSecond()).getDefaultValue()));
writer.write(values.getSecond() == null ? "&lt;none&gt;" : escapeHtml4(convertToMlText((Map) values.getSecond()).getDefaultValue()));
}
else
{
Serializable oldValue = values.getFirst();
writer.write(oldValue == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(oldValue.toString()));
writer.write(oldValue == null ? "&lt;none&gt;" : escapeHtml4(oldValue.toString()));
writer.write("</td><td>");
Serializable newValue = values.getSecond();
writer.write(newValue == null ? "&lt;none&gt;" : StringEscapeUtils.escapeHtml(newValue.toString()));
writer.write(newValue == null ? "&lt;none&gt;" : escapeHtml4(newValue.toString()));
}
writer.write("</td></tr>");
@@ -1416,29 +1421,33 @@ public class RecordsManagementAuditServiceImpl extends AbstractLifecycleBean
case "Delete Person":
nodeName = getNodeName(entry.getBeforeProperties(), PROP_USERNAME);
json.put("deletePerson", true);
json.put("noAvailableLink", true);
break;
case "Create User Group":
nodeName = getNodeName(entry.getAfterProperties(), PROP_AUTHORITY_DISPLAY_NAME, PROP_AUTHORITY_NAME);
json.put("noAvailableLink", true);
break;
case "Delete User Group":
nodeName = getNodeName(entry.getBeforeProperties(), PROP_AUTHORITY_DISPLAY_NAME, PROP_AUTHORITY_NAME);
json.put("noAvailableLink", true);
break;
case "Add To User Group":
nodeName = getNodeName(entry.getAfterProperties(), PARENT_GROUP);
json.put("noAvailableLink", true);
break;
case "Remove From User Group":
nodeName = getNodeName(entry.getBeforeProperties(), PARENT_GROUP);
json.put("noAvailableLink", true);
break;
case "Delete RM Object":
case "Delete Hold":
nodeName = entry.getNodeName();
json.put("deleteObject", true);
json.put("noAvailableLink", true);
break;
default:
@@ -31,7 +31,7 @@ import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.module.org_alfresco_module_rm.audit.RecordsManagementAuditService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -135,7 +135,8 @@ public final class NamePathDataExtractor extends AbstractDataExtractor
{
// Get path from the RM root
List<NodeRef> nodeRefPath = filePlanService.getNodeRefPath(nodeRef);
NodeRef filePlan = filePlanService.getFilePlan(nodeRef);
nodeRefPath.add(0, nodeService.getPrimaryParent(filePlan).getParentRef());
for (NodeRef pathNodeRef : nodeRefPath)
{
String name = (String) nodeService.getProperty(pathNodeRef, ContentModel.PROP_NAME);
@@ -31,7 +31,7 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.capability;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -64,7 +64,7 @@ import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.PermissionEvaluationMode;
import org.alfresco.service.cmr.search.ResultSet;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
@@ -44,7 +44,7 @@ import org.alfresco.module.org_alfresco_module_rm.util.TransactionalResourceHelp
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.dataset;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
public class DataSetBase implements DataSet
@@ -237,6 +237,14 @@ public interface DispositionService
*/
void updateNextDispositionAction(NodeRef nodeRef);
/**
* Updates the next disposition action
*
* @param nodeRef node reference
* @param dispositionSchedule the schedule to be applied
*/
void updateNextDispositionAction(NodeRef nodeRef, DispositionSchedule dispositionSchedule);
/**
* Refreshes the disposition action details of the given node.
*
@@ -977,8 +977,36 @@ public class DispositionServiceImpl extends ServiceBaseImpl
public Void doWork()
{
// Get this disposition instructions for the node
DispositionSchedule di = getDispositionSchedule(nodeRef);
if (di != null)
DispositionSchedule dispositionSchedule = getDispositionSchedule(nodeRef);
updateNextDispositionAction(nodeRef, dispositionSchedule);
return null;
}
};
AuthenticationUtil.runAsSystem(runAsWork);
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService#updateNextDispositionAction(NodeRef)
*/
@Override
public void updateNextDispositionAction(final NodeRef nodeRef, final DispositionSchedule dispositionSchedule)
{
RunAsWork<Void> runAsWork = new RunAsWork<Void>()
{
/**
* @see org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork#doWork()
*/
@Override
public Void doWork()
{
if (dispositionSchedule != null)
{
// Get the current action node
NodeRef currentDispositionAction = null;
@@ -997,7 +1025,7 @@ public class DispositionServiceImpl extends ServiceBaseImpl
nodeService.moveNode(currentDispositionAction, nodeRef, ASSOC_DISPOSITION_ACTION_HISTORY, ASSOC_DISPOSITION_ACTION_HISTORY);
}
List<DispositionActionDefinition> dispositionActionDefinitions = di.getDispositionActionDefinitions();
List<DispositionActionDefinition> dispositionActionDefinitions = dispositionSchedule.getDispositionActionDefinitions();
DispositionActionDefinition currentDispositionActionDefinition = null;
DispositionActionDefinition nextDispositionActionDefinition = null;
@@ -1013,14 +1041,14 @@ public class DispositionServiceImpl extends ServiceBaseImpl
{
// Get the current action
String currentADId = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION_ID);
currentDispositionActionDefinition = di.getDispositionActionDefinition(currentADId);
currentDispositionActionDefinition = dispositionSchedule.getDispositionActionDefinition(currentADId);
// When the record has multiple disposition schedules the current disposition action may not be found by id
// In this case it will be searched by name
if(currentDispositionActionDefinition == null)
{
String currentADName = (String) nodeService.getProperty(currentDispositionAction, PROP_DISPOSITION_ACTION);
currentDispositionActionDefinition = di.getDispositionActionDefinitionByName(currentADName);
currentDispositionActionDefinition = dispositionSchedule.getDispositionActionDefinitionByName(currentADName);
}
// Get the next disposition action
@@ -53,7 +53,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
@@ -53,7 +53,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -232,6 +232,8 @@ public class HoldServiceImpl extends ServiceBaseImpl
{
if (nodeService.exists(hold) && isHold(hold))
{
checkPermissionsForDeleteHold(hold);
RunAsWork<Void> work = new RunAsWork<Void>()
{
@Override
@@ -522,14 +524,25 @@ public class HoldServiceImpl extends ServiceBaseImpl
throw new AlfrescoRuntimeException("Can't delete hold, because passed node is not a hold. (hold=" + hold.toString() + ")");
}
List<NodeRef> held = AuthenticationUtil.runAsSystem(new RunAsWork<List<NodeRef>>()
{
@Override
public List<NodeRef> doWork()
{
return getHeld(hold);
}
});
invokeBeforeDeleteHold(hold);
String holdName = (String) nodeService.getProperty(hold, PROP_NAME);
Set<QName> classQNames = getTypeAndApsects(hold);
// delete the hold node
nodeService.deleteNode(hold);
invokeOnDeleteHold(holdName, classQNames);
}
/**
* Helper method to check if user has correct permissions to delete hold
*
* @param hold hold to be deleted
*/
private void checkPermissionsForDeleteHold(NodeRef hold)
{
List<NodeRef> held = AuthenticationUtil.runAsSystem(() -> getHeld(hold));
List<String> heldNames = new ArrayList<>();
for (NodeRef nodeRef : held)
@@ -570,16 +583,6 @@ public class HoldServiceImpl extends ServiceBaseImpl
});
throw new AccessDeniedException(I18NUtil.getMessage(MSG_ERR_HOLD_PERMISSION_DETAILED_ERROR) + sb.toString());
}
invokeBeforeDeleteHold(hold);
String holdName = (String) nodeService.getProperty(hold, PROP_NAME);
Set<QName> classQNames = getTypeAndApsects(hold);
// delete the hold node
nodeService.deleteNode(hold);
invokeOnDeleteHold(holdName, classQNames);
}
/**
@@ -67,7 +67,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PathUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -288,9 +288,9 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
QName PROP_COUNT = QName.createQName(RM_URI, "count");
QName ASPECT_SAVED_SEARCH = QName.createQName(RM_URI, "savedSearch");
//Workaround for RM-6788
String GL_URI = "http://www.alfresco.org/model/glacier/1.0";
QName ASPECT_ARCHIVED = QName.createQName(GL_URI, "archived");
QName ASPECT_DISPOSITION_PROCESSED = QName.createQName(RM_URI, "dispositionProcessed");
}
@@ -50,9 +50,12 @@ import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderService;
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordDefinition;
import org.alfresco.module.org_alfresco_module_rm.vital.VitalRecordService;
import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
import org.alfresco.repo.policy.annotation.Behaviour;
import org.alfresco.repo.policy.annotation.BehaviourKind;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.transaction.TransactionalResourceHelper;
@@ -74,7 +77,8 @@ import org.apache.commons.logging.LogFactory;
* @author Roy Wetherall
* @since 1.0
*/
public class RecordsManagementSearchBehaviour implements RecordsManagementModel
public class RecordsManagementSearchBehaviour implements RecordsManagementModel,
NodeServicePolicies.OnMoveNodePolicy
{
/** logger */
private static Log logger = LogFactory.getLog(RecordsManagementSearchBehaviour.class);
@@ -187,6 +191,9 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
private JavaBehaviour jbEventExecutionUpdate = new JavaBehaviour(this, "eventExecutionUpdate", NotificationFrequency.TRANSACTION_COMMIT);
private JavaBehaviour jbEventExecutionDelete = new JavaBehaviour(this, "eventExecutionDelete", NotificationFrequency.TRANSACTION_COMMIT);
/** on move record or record folder behavior */
private JavaBehaviour jbMoveNode = new JavaBehaviour(this, "onMoveNode", NotificationFrequency.TRANSACTION_COMMIT);
/** Array of behaviours related to disposition schedule artifacts */
private JavaBehaviour[] jbDispositionBehaviours =
{
@@ -263,6 +270,11 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"),
ASPECT_VITAL_RECORD_DEFINITION,
new JavaBehaviour(this, "vitalRecordDefintionUpdateProperties", NotificationFrequency.TRANSACTION_COMMIT));
this.policyComponent.bindClassBehaviour(
QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"),
ASPECT_FILE_PLAN_COMPONENT,
jbMoveNode);
}
/**
@@ -976,4 +988,37 @@ public class RecordsManagementSearchBehaviour implements RecordsManagementModel
return results;
}
/**
* Record and record folder move behavior
*
* @see org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy#onMoveNode(org.alfresco.service.cmr.repository.ChildAssociationRef, org.alfresco.service.cmr.repository.ChildAssociationRef)
*/
@Override
@Behaviour
(
kind = BehaviourKind.CLASS,
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
)
public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef)
{
// check the parent has actually changed
if (!oldChildAssocRef.getParentRef().equals(newChildAssocRef.getParentRef()))
{
final NodeRef recordOrFolder = newChildAssocRef.getChildRef();
final boolean isRecordOrFolder = recordService.isRecord(recordOrFolder) || recordFolderService.isRecordFolder(recordOrFolder);
AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Void>()
{
@Override
public Void doWork()
{
if (nodeService.exists(recordOrFolder) && isRecordOrFolder)
{
applySearchAspect(recordOrFolder);
}
return null;
}
});
}
}
}
@@ -51,7 +51,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -58,7 +58,7 @@ import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
@@ -0,0 +1,88 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2019 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* 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/>.
* #L%
*/
package org.alfresco.module.org_alfresco_module_rm.query;
/**
* NodeRef Entity - used by {@link RecordsManagementQueryDAOImpl}.
*
* @author Tom Page
* @since 2.5.0.4
*/
public class NodeRefEntity
{
private Long num;
private String protocol;
private String identifier;
private String uuid;
/**
* Default constructor.
*/
public NodeRefEntity()
{
}
public Long getNum()
{
return num;
}
public void setNum(Long num)
{
this.num = num;
}
public String getProtocol()
{
return protocol;
}
public void setProtocol(String protocol)
{
this.protocol = protocol;
}
public String getIdentifier()
{
return identifier;
}
public void setIdentifier(String identifier)
{
this.identifier = identifier;
}
public String getUuid()
{
return uuid;
}
public void setUuid(String uuid)
{
this.uuid = uuid;
}
}
@@ -27,9 +27,11 @@
package org.alfresco.module.org_alfresco_module_rm.query;
import java.util.List;
import java.util.Set;
import org.alfresco.service.cmr.repository.NodeRef;
import java.util.Collection;
import org.alfresco.service.namespace.QName;
@@ -54,6 +56,17 @@ public interface RecordsManagementQueryDAO
int getCountRmaIdentifier(String identifierValue);
/**
* Returns a number of nodeRefs for record folders in the system
* that have the property recordSearchHasDispositionSchedule:true
* (used for MNT-20864)
* @param start long - the first result row to return
* @param end long - the last result row to return
* @return list of node refs
*/
List<NodeRef> getRecordFoldersWithSchedules(Long start, Long end);
/**
* Returns whether a given node contains children with one of the given values for the given property
* Returns distinct property values from children for the given property
*
* @param parent the parent to evaluate
@@ -63,7 +76,7 @@ public interface RecordsManagementQueryDAO
public Set<String> getChildrenStringPropertyValues(NodeRef parent, QName property);
/**
* @param contentUrl the URL of the content url entity
* @param contentUrl the URL of the content url entity
* @return Set<NodeRef> a set of nodes that reference the given content url
*/
Set<NodeRef> getNodeRefsWhichReferenceContentUrl(String contentUrl);
@@ -27,8 +27,11 @@
package org.alfresco.module.org_alfresco_module_rm.query;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -56,33 +59,43 @@ import org.mybatis.spring.SqlSessionTemplate;
*/
public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO, RecordsManagementModel
{
/** logger */
@SuppressWarnings ("unused")
/**
* logger
*/
@SuppressWarnings("unused")
private static final Log logger = LogFactory.getLog(RecordsManagementQueryDAOImpl.class);
/** query names */
/**
* query names
*/
private static final String COUNT_IDENTIFIER = "alfresco.query.rm.select_CountRMIndentifier";
private static final String GET_CHILDREN_PROPERTY_VALUES = "select_GetStringPropertyValuesOfChildren";
private static final String SELECT_NODE_IDS_WHICH_REFERENCE_CONTENT_URL = "select_NodeIdsWhichReferenceContentUrl";
private static final String SCHEDULED_FOLDERS = "alfresco.query.rm.select_RecordFoldersWithSchedules";
private static final String SCHEDULED_FOLDERS_COUNT = "alfresco.query.rm.select_RecordFoldersWithSchedulesCount";
/** SQL session template */
/**
* SQL session template
*/
protected SqlSessionTemplate template;
/** QName DAO */
/**
* QName DAO
*/
protected QNameDAO qnameDAO;
protected NodeDAO nodeDAO;
protected TenantService tenantService;
/**
* @param sqlSessionTemplate SQL session template
* @param sqlSessionTemplate SQL session template
*/
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate)
{
this.template = sqlSessionTemplate;
}
/**
* @param qnameDAO qname DAO
* @param qnameDAO qname DAO
*/
public final void setQnameDAO(QNameDAO qnameDAO)
{
@@ -106,25 +119,25 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
public int getCountRmaIdentifier(String identifierValue)
{
int result = 0;
// lookup the id of the identifier property qname
Pair<Long, QName> pair = qnameDAO.getQName(PROP_IDENTIFIER);
if (pair != null)
{
{
// create query params
Map<String, Object> params = new HashMap<>(2);
params.put("qnameId", pair.getFirst());
params.put("idValue", identifierValue);
// return the number of rma identifiers found that match the passed value
Integer count = (Integer)template.selectOne(COUNT_IDENTIFIER, params);
Integer count = (Integer) template.selectOne(COUNT_IDENTIFIER, params);
if (count != null)
{
result = count;
}
}
return result;
}
@@ -158,8 +171,8 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
/**
* Get a set of node reference which reference the provided content URL
*
* @param String contentUrl content URL
* @return Set<NodeRef> set of nodes that reference the provided content URL
* @param String contentUrl content URL
*/
@Override
public Set<NodeRef> getNodeRefsWhichReferenceContentUrl(String contentUrl)
@@ -208,14 +221,16 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
if (logger.isDebugEnabled())
{
logMessage.append(nodeRefToAdd).append(" (from version)");
logMessage.append(nodeRefToAdd)
.append(" (from version)");
}
}
// add the node ref of the referencing node
else
{
nodeRefToAdd = nodeDAO.getNodeIdStatus(nodeId).getNodeRef();
nodeRefToAdd = nodeDAO.getNodeIdStatus(nodeId)
.getNodeRef();
if (logger.isDebugEnabled())
{
logMessage.append(nodeRefToAdd);
@@ -240,4 +255,33 @@ public class RecordsManagementQueryDAOImpl implements RecordsManagementQueryDAO,
return nodesReferencingContentUrl;
}
/**
* @see org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO#getRecordFoldersWithSchedules(Long, Long)
*/
@Override
public List<NodeRef> getRecordFoldersWithSchedules(Long start, Long end)
{
Map<String, Object> params = new HashMap<>(2);
params.put("processed", qnameDAO.getQName(ASPECT_DISPOSITION_PROCESSED)
.getFirst());
params.put("folderQnameId", qnameDAO.getQName(TYPE_RECORD_FOLDER)
.getFirst());
params.put("start", start);
params.put("end", end);
List<NodeRefEntity> entities = template.selectList(SCHEDULED_FOLDERS, params);
List<NodeRef> results = new ArrayList<>();
// convert the entities to NodeRefs
for (NodeRefEntity nodeRefEntity : entities)
{
results.add(
new NodeRef(nodeRefEntity.getProtocol(), nodeRefEntity.getIdentifier(), nodeRefEntity.getUuid()));
}
return results;
}
}
@@ -122,8 +122,8 @@ import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.alfresco.util.PropertyMap;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.extensions.surf.util.I18NUtil;
@@ -32,7 +32,7 @@ import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagement
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_ORIGIONAL_NAME;
import static org.alfresco.module.org_alfresco_module_rm.record.RecordUtils.appendIdentifierToName;
import static org.alfresco.util.ParameterCheck.mandatory;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.Serializable;
import java.util.HashMap;
@@ -30,7 +30,7 @@ package org.alfresco.module.org_alfresco_module_rm.recordableversion;
import static org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionPolicy.NONE;
import static org.alfresco.util.ParameterCheck.mandatory;
import static org.alfresco.util.ParameterCheck.mandatoryString;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList;
import java.util.List;
@@ -30,7 +30,7 @@ package org.alfresco.module.org_alfresco_module_rm.relationship;
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.ASPECT_FROZEN;
import static org.alfresco.util.ParameterCheck.mandatory;
import static org.alfresco.util.ParameterCheck.mandatoryString;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isBlank;
import java.util.HashSet;
import java.util.List;
@@ -54,7 +54,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.UrlUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
/**
@@ -43,7 +43,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Transfer report generator.
@@ -54,7 +54,7 @@ import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -37,7 +37,7 @@ import org.alfresco.module.org_alfresco_module_rm.recordfolder.RecordFolderServi
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
@@ -28,7 +28,7 @@
package org.alfresco.module.org_alfresco_module_rm.script;
import static org.alfresco.util.WebScriptUtils.getStringValueFromJSONObject;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isBlank;
import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipDisplayName;
import org.alfresco.module.org_alfresco_module_rm.relationship.RelationshipService;
@@ -35,7 +35,7 @@ import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.Cache;
@@ -37,7 +37,7 @@ import org.alfresco.module.org_alfresco_module_rm.dataset.DataSetService;
import org.alfresco.module.org_alfresco_module_rm.model.rma.type.RmSiteType;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
@@ -27,6 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.script;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -39,8 +40,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementActionService;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
@@ -56,7 +55,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
@@ -292,7 +291,7 @@ public class TransferReportPost extends BaseTransferWebScript
writer.write("<table cellpadding=\"3\" cellspacing=\"3\">");
writer.write("<tr><td class=\"label\">Transfer Date:</td><td>");
Date transferDate = (Date)this.nodeService.getProperty(transferNode, ContentModel.PROP_CREATED);
writer.write(StringEscapeUtils.escapeHtml(transferDate.toString()));
writer.write(StringEscapeUtils.escapeHtml4(transferDate.toString()));
writer.write("</td></tr>");
writer.write("<tr><td class=\"label\">Transfer Location:</td><td>");
if (isAccession)
@@ -301,16 +300,16 @@ public class TransferReportPost extends BaseTransferWebScript
}
else
{
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(transferNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(transferNode,
RecordsManagementModel.PROP_TRANSFER_LOCATION)));
}
writer.write("</td></tr>");
writer.write("<tr><td class=\"label\">Performed By:</td><td>");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(transferNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(transferNode,
ContentModel.PROP_CREATOR)));
writer.write("</td></tr>");
writer.write("<tr><td class=\"label\">Disposition Authority:</td><td>");
writer.write(dispositionAuthority != null ? StringEscapeUtils.escapeHtml(dispositionAuthority) : "");
writer.write(dispositionAuthority != null ? StringEscapeUtils.escapeHtml4(dispositionAuthority) : "");
writer.write("</td></tr></table>\n");
writer.write("<h2>Transferred Items</h2>\n");
@@ -361,10 +360,10 @@ public class TransferReportPost extends BaseTransferWebScript
throws IOException
{
writer.write("<span class=\"nodeName\">");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(folderNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(folderNode,
ContentModel.PROP_NAME)));
writer.write("</span>&nbsp;(Unique Folder Identifier:&nbsp;");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(folderNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(folderNode,
RecordsManagementModel.PROP_IDENTIFIER)));
writer.write(")\n");
@@ -399,10 +398,10 @@ public class TransferReportPost extends BaseTransferWebScript
{
writer.write("<div class=\"record\">\n");
writer.write(" <span class=\"nodeName\">");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(recordNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(recordNode,
ContentModel.PROP_NAME)));
writer.write("</span>&nbsp;(Unique Record Identifier:&nbsp;");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(recordNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(recordNode,
RecordsManagementModel.PROP_IDENTIFIER)));
writer.write(")");
@@ -410,10 +409,10 @@ public class TransferReportPost extends BaseTransferWebScript
{
Date declaredOn = (Date)this.nodeService.getProperty(recordNode, RecordsManagementModel.PROP_DECLARED_AT);
writer.write(" declared by ");
writer.write(StringEscapeUtils.escapeHtml((String)this.nodeService.getProperty(recordNode,
writer.write(StringEscapeUtils.escapeHtml4((String)this.nodeService.getProperty(recordNode,
RecordsManagementModel.PROP_DECLARED_BY)));
writer.write(" on ");
writer.write(StringEscapeUtils.escapeHtml(declaredOn.toString()));
writer.write(StringEscapeUtils.escapeHtml4(declaredOn.toString()));
}
writer.write("\n</div>\n");
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.script.admin;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
@@ -35,7 +35,7 @@ import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService;
import org.alfresco.util.GUID;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
@@ -31,7 +31,7 @@ import java.util.HashMap;
import java.util.Map;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
@@ -39,7 +39,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.WebScriptRequest;
@@ -41,7 +41,7 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
@@ -43,7 +43,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
@@ -53,8 +53,8 @@ import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.extensions.webscripts.Cache;
@@ -34,7 +34,7 @@ import static org.alfresco.repo.policy.annotation.BehaviourKind.CLASS;
import static org.alfresco.repo.security.authentication.AuthenticationUtil.getSystemUserName;
import static org.alfresco.service.cmr.security.OwnableService.NO_OWNER;
import static org.alfresco.util.ParameterCheck.mandatory;
import static org.apache.commons.lang.BooleanUtils.isTrue;
import static org.apache.commons.lang3.BooleanUtils.isTrue;
import java.io.Serializable;
import java.util.HashMap;
@@ -55,7 +55,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.I18NUtil;
import org.springframework.extensions.surf.util.ParameterCheck;
@@ -27,7 +27,7 @@
package org.alfresco.module.org_alfresco_module_rm.util;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Utility class that contains validation not present in {@link org.alfresco.util.ParameterCheck}.
@@ -64,7 +64,7 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.alfresco.util.PropertyMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
@@ -34,7 +34,7 @@ import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Date parameter processor.
@@ -45,7 +45,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.ArrayUtils;
/**
* Node parameter processor.
@@ -27,7 +27,7 @@
package org.alfresco.repo.security.permissions.impl;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.Serializable;
import java.util.Arrays;
@@ -57,7 +57,7 @@ import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.Pair;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEvent;
@@ -29,7 +29,7 @@ package org.alfresco.repo.web.scripts.dictionary;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.WebScriptRequest;
/**
@@ -31,7 +31,7 @@ import java.util.Map;
import org.alfresco.module.org_alfresco_module_rm.script.admin.RoleDeclarativeWebScript;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
@@ -44,6 +44,7 @@
*/
package org.alfresco.repo.web.scripts.roles;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
@@ -58,8 +59,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedReaderDynamicAuthority;
@@ -79,7 +78,7 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.Pair;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.AbstractWebScript;
@@ -0,0 +1,443 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2019 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
* -
* 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/>.
* #L%
*/
/*
* Copyright (C) 2005-2014 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.repo.web.scripts.schedule;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule;
import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.model.behaviour.RecordsManagementSearchBehaviour;
import org.alfresco.module.org_alfresco_module_rm.model.rma.aspect.FrozenAspect;
import org.alfresco.module.org_alfresco_module_rm.query.RecordsManagementQueryDAO;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.webscripts.AbstractWebScript;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.Format;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
/**
* Webscript used to update records that are missing their schedule information
*
* @author Roy Wetherall
*/
public class UpdateRecordScheduleGet extends AbstractWebScript implements RecordsManagementModel
{
/**
* logger
*/
private static Log logger = LogFactory.getLog(UpdateRecordScheduleGet.class);
/**
* parameters
*/
private static final String PARAM_MAX_RECORD_FOLDERS = "maxRecordFolders";
private static final String PARAM_RECORD_FOLDER = "recordFolder";
private static final String SUCCESS_STATUS = "success";
private static final String MODEL_STATUS = "responsestatus";
private static final String MODEL_MESSAGE = "message";
private static final String MESSAGE_ALL_TEMPLATE = "Updated {0} records from {1} folders with updated disposition instructions.";
private static final String MESSAGE_FOLDER_TEMPLATE = "Updated records in folder {0} with updated disposition instructions.";
/**
* services
*/
private NodeService nodeService;
private DispositionService dispositionService;
private RecordService recordService;
private TransactionService transactionService;
private RecordsManagementQueryDAO recordsManagementQueryDAO;
private BehaviourFilter behaviourFilter;
private NodeDAO nodeDAO;
private QNameDAO qnameDAO;
private FrozenAspect frozenAspect;
private RecordsManagementSearchBehaviour recordsManagementSearchBehaviour;
/**
* service setters
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setRecordsManagementQueryDAO(RecordsManagementQueryDAO recordsManagementQueryDAO)
{
this.recordsManagementQueryDAO = recordsManagementQueryDAO;
}
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
public void setDispositionService(DispositionService dispositionService)
{
this.dispositionService = dispositionService;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public void setBehaviourFilter(BehaviourFilter behaviourFilter)
{
this.behaviourFilter = behaviourFilter;
}
public void setNodeDAO(NodeDAO nodeDAO)
{
this.nodeDAO = nodeDAO;
}
public void setQnameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
public void setFrozenAspect(FrozenAspect frozenAspect)
{
this.frozenAspect = frozenAspect;
}
public void setRecordsManagementSearchBehaviour(RecordsManagementSearchBehaviour recordsManagementSearchBehaviour)
{
this.recordsManagementSearchBehaviour = recordsManagementSearchBehaviour;
}
/**
* Build web script model
*/
protected Map<String, Object> buildModel(WebScriptRequest req, WebScriptResponse res) throws IOException
{
Map<String, Object> model = new HashMap<>();
transactionService.getRetryingTransactionHelper()
.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<String>()
{
public String execute() throws Throwable
{
qnameDAO.getOrCreateQName(ASPECT_DISPOSITION_PROCESSED);
return null;
}
}, false, true);
int maxRecordFolders = getMaxRecordFolders(req);
NodeRef recordFolder = getRecordFolder(req);
int processedRecords = 0;
String message;
if (recordFolder != null)
{
// Process the specified record folder
updateRecordFolder(recordFolder);
message = MessageFormat.format(MESSAGE_FOLDER_TEMPLATE, recordFolder);
}
else
{
int processedRecordFolders = 0;
int queryBatchSize = 10000;
Long maxNodeId = nodeDAO.getMaxNodeId();
for (Long i = 0L; i < maxNodeId; i += queryBatchSize)
{
List<NodeRef> folders = recordsManagementQueryDAO.getRecordFoldersWithSchedules(i, i + queryBatchSize);
for (NodeRef folder : folders)
{
processedRecords = processedRecords + updateRecordFolder(folder);
processedRecordFolders++;
if (processedRecordFolders >= maxRecordFolders)
{
// stop processing since we have meet our limit
break;
}
}
if (processedRecordFolders >= maxRecordFolders)
{
// stop processing since we have meet our limit
break;
}
}
message = MessageFormat.format(MESSAGE_ALL_TEMPLATE, processedRecords, processedRecordFolders);
}
model.put(MODEL_STATUS, SUCCESS_STATUS);
model.put(MODEL_MESSAGE, message);
logger.info(message);
return model;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.web.scripts.content.StreamContent#execute(org.springframework.extensions.webscripts.
* WebScriptRequest, org.springframework.extensions.webscripts.WebScriptResponse)
*/
@Override
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException
{
// retrieve requested format
String format = req.getFormat();
try
{
String mimetype = getContainer().getFormatRegistry()
.getMimeType(req.getAgent(), format);
if (mimetype == null)
{
throw new WebScriptException("Web Script format '" + format + "' is not registered");
}
// construct model for script / template
Status status = new Status();
Cache cache = new Cache(getDescription().getRequiredCache());
Map<String, Object> model = buildModel(req, res);
if (model == null) { return; }
model.put("status", status);
model.put("cache", cache);
Map<String, Object> templateModel = createTemplateParameters(req, res, model);
// render output
int statusCode = status.getCode();
if (statusCode != HttpServletResponse.SC_OK && !req.forceSuccessStatus())
{
if (logger.isDebugEnabled())
{
logger.debug("Force success status header in response: " + req.forceSuccessStatus());
logger.debug("Setting status " + statusCode);
}
res.setStatus(statusCode);
}
// apply location
String location = status.getLocation();
if (location != null && location.length() > 0)
{
if (logger.isDebugEnabled())
logger.debug("Setting location to " + location);
res.setHeader(WebScriptResponse.HEADER_LOCATION, location);
}
// apply cache
res.setCache(cache);
String callback = null;
if (getContainer().allowCallbacks())
{
callback = req.getJSONCallback();
}
if (format.equals(WebScriptResponse.JSON_FORMAT) && callback != null)
{
if (logger.isDebugEnabled())
logger.debug(
"Rendering JSON callback response: content type=" + Format.JAVASCRIPT.mimetype() + ", status="
+ statusCode + ", callback=" + callback);
// NOTE: special case for wrapping JSON results in a javascript function callback
res.setContentType(Format.JAVASCRIPT.mimetype() + ";charset=UTF-8");
res.getWriter()
.write((callback + "("));
}
else
{
if (logger.isDebugEnabled())
logger.debug("Rendering response: content type=" + mimetype + ", status=" + statusCode);
res.setContentType(mimetype + ";charset=UTF-8");
}
// render response according to requested format
renderFormatTemplate(format, templateModel, res.getWriter());
if (format.equals(WebScriptResponse.JSON_FORMAT) && callback != null)
{
// NOTE: special case for wrapping JSON results in a javascript function callback
res.getWriter()
.write(")");
}
}
catch (Throwable e)
{
if (logger.isDebugEnabled())
{
StringWriter stack = new StringWriter();
e.printStackTrace(new PrintWriter(stack));
logger.debug("Caught exception; decorating with appropriate status template : " + stack.toString());
}
throw createStatusException(e, req, res);
}
}
protected void renderFormatTemplate(String format, Map<String, Object> model, Writer writer)
{
format = (format == null) ? "" : format;
String templatePath = getDescription().getId() + "." + format;
if (logger.isDebugEnabled())
logger.debug("Rendering template '" + templatePath + "'");
renderTemplate(templatePath, model, writer);
}
protected int getMaxRecordFolders(WebScriptRequest req)
{
String valueStr = req.getParameter(PARAM_MAX_RECORD_FOLDERS);
int value = Integer.MAX_VALUE;
if (StringUtils.isNotBlank(valueStr))
{
try
{
value = Integer.parseInt(valueStr);
}
catch (NumberFormatException ex)
{
//do nothing here, the value will remain 0L in this case
}
}
return value;
}
protected NodeRef getRecordFolder(WebScriptRequest req)
{
String valueStr = req.getParameter(PARAM_RECORD_FOLDER);
NodeRef value = null;
if (StringUtils.isNotBlank(valueStr))
{
value = new NodeRef(valueStr);
}
return value;
}
private int updateRecordFolder(final NodeRef recordFolder)
{
return transactionService.getRetryingTransactionHelper()
.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Integer>()
{
public Integer execute() throws Throwable
{
int recordCount = 0;
frozenAspect.disableOnPropUpdateFrozenAspect();
try
{
if (logger.isDebugEnabled())
{
logger.info("Checking folder: " + recordFolder);
}
recordCount = AuthenticationUtil.runAsSystem(new AuthenticationUtil.RunAsWork<Integer>()
{
@Override
public Integer doWork() throws Exception
{
DispositionSchedule schedule = dispositionService.getDispositionSchedule(recordFolder);
int innerRecordCount = 0;
if (schedule != null && schedule.isRecordLevelDisposition())
{
List<NodeRef> records = recordService.getRecords(recordFolder);
for (NodeRef record : records)
{
if (!nodeService.hasAspect(record, ASPECT_DISPOSITION_LIFECYCLE))
{
if (recordFolder.equals(nodeService.getPrimaryParent(record).getParentRef()))
{
if (logger.isDebugEnabled())
{
logger.info("updating record: " + record);
}
// update record disposition information
dispositionService.updateNextDispositionAction(record, schedule);
recordsManagementSearchBehaviour.onAddDispositionLifecycleAspect(record,null);
innerRecordCount++;
}
}
}
}
return innerRecordCount;
}
});
nodeService.addAspect(recordFolder, ASPECT_DISPOSITION_PROCESSED, null);
}
finally
{
frozenAspect.enableOnPropUpdateFrozenAspect();
}
return recordCount;
}
}, false, true);
}
}
@@ -44,7 +44,7 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
@@ -100,7 +100,7 @@ import org.alfresco.service.cmr.usage.ContentQuotaException;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,7 +31,7 @@ import java.util.Map;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.surf.util.Content;
import org.springframework.extensions.webscripts.servlet.FormData;
@@ -42,7 +42,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Util class for the request info workflow
@@ -42,7 +42,7 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
/**
@@ -43,7 +43,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.GUID;
@@ -120,7 +120,7 @@ public class MoveRecordTest extends BaseRMTestCase
assertNull(dispositionService.getNextDispositionAction(record));
// check the search aspect properties
assertFalse(nodeService.hasAspect(record, ASPECT_RM_SEARCH));
assertTrue(nodeService.hasAspect(record, ASPECT_RM_SEARCH));
}
});
@@ -218,7 +218,7 @@ public class MoveRecordFolderTest extends BaseRMTestCase
assertNull(dispositionService.getNextDispositionAction(recordFolder));
// check the search aspect properties
assertFalse(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH));
assertTrue(nodeService.hasAspect(recordFolder, ASPECT_RM_SEARCH));
}
});
}
@@ -82,6 +82,10 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
//remove the content property as ContentPropertyRestrictionInterceptor will not allow update of
// content property via NodeService.addProperties
nodeService.removeProperty(dmDocument, ContentModel.PROP_CONTENT);
// create version
versionService.createVersion(dmDocument, versionProperties);
@@ -184,7 +188,9 @@ public class DeclareAsRecordVersionTest extends RecordableVersionsBaseTest
versionProperties = new HashMap<>(2);
versionProperties.put(Version.PROP_DESCRIPTION, DESCRIPTION);
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
//remove the content property as ContentPropertyRestrictionInterceptor will not allow update of
// content property via NodeService.addProperties
nodeService.removeProperty(customDocument, PROP_CONTENT);
// create version
versionService.createVersion(customDocument, versionProperties);
@@ -33,7 +33,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.extensions.webscripts.GUID;
/**
@@ -32,7 +32,7 @@ import java.io.Serializable;
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase;
import org.alfresco.repo.jscript.app.JSONConversionComponent;
import org.alfresco.service.cmr.repository.NodeRef;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.json.JSONException;
import org.json.JSONObject;
@@ -46,7 +46,7 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* Report service implementation unit test.
@@ -65,7 +65,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
/**
@@ -4,7 +4,7 @@
# Version label
version.major=6
version.minor=1
version.minor=2
version.revision=0
version.label=
@@ -88,6 +88,7 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
private static final String HOLD_NAME = "holdname";
private static final String HOLD_REASON = "holdreason";
private static final String HOLD_DESCRIPTION = "holddescription";
private static final String GENERIC_ERROR_MSG = "any error message text";
protected NodeRef holdContainer;
protected NodeRef hold;
@@ -319,6 +320,21 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
// TODO check interactions with policy component!!!
}
@Test (expected = AccessDeniedException.class)
public void deleteHoldNoPermissionsOnContent()
{
mockPoliciesForDeleteHold();
ChildAssociationRef childAssociationRef = generateChildAssociationRef(hold, record);
when(mockedNodeService.getChildAssocs(hold, ASSOC_FROZEN_CONTENT, RegexQNamePattern.MATCH_ALL))
.thenReturn(Collections.singletonList(childAssociationRef));
when(mockedPermissionService.hasPermission(record, RMPermissionModel.FILING)).thenReturn(AccessStatus.DENIED);
when(mockedNodeService.getProperty(record, ContentModel.PROP_NAME)).thenThrow(new AccessDeniedException(GENERIC_ERROR_MSG));
holdService.beforeDeleteNode(hold);
}
@Test (expected = IntegrityException.class)
public void addToHoldNotAHold()
{
@@ -577,51 +593,53 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
}
/**
* test delete hold throws exception for failed read permission check for content
* test before delete node throws exception for failed read permission check for content
*/
@Test (expected = AccessDeniedException.class)
public void testDeleteHoldThrowsExceptionForActiveContentWithoutReadPermission()
public void testBeforeDeleteNodeThrowsExceptionForActiveContentWithoutReadPermission()
{
NodeRef heldContent = generateNodeRef(TYPE_CONTENT);
List<ChildAssociationRef> holds = createListOfHoldAssociations(heldContent);
mockPoliciesForExistingHoldWithHeldItems(hold, heldContent);
when(mockedNodeService.getChildAssocs(hold, ASSOC_FROZEN_CONTENT, RegexQNamePattern.MATCH_ALL)).thenReturn(holds);
// mocks for held content
when(mockedRecordService.isRecord(heldContent)).thenReturn(false);
when(mockedRecordFolderService.isRecordFolder(heldContent)).thenReturn(false);
when(mockedPermissionService.hasPermission(heldContent, PermissionService.READ)).thenReturn(AccessStatus.DENIED);
when(mockedNodeService.getProperty(heldContent, ContentModel.PROP_NAME)).thenReturn("foo");
holdService.deleteHold(hold);
holdService.beforeDeleteNode(hold);
}
/**
* test delete hold throws exception for failed read permission check for records
* test before delete node throws exception for failed read permission check for records
*/
@Test (expected = AccessDeniedException.class)
public void testDeleteHoldThrowsExceptionForARecordWithoutReadPermission()
public void testBeforeDeleteNodeThrowsExceptionForARecordWithoutReadPermission()
{
NodeRef heldContent = generateNodeRef();
List<ChildAssociationRef> holds = createListOfHoldAssociations(heldContent);
mockPoliciesForExistingHoldWithHeldItems(hold, heldContent);
when(mockedNodeService.getChildAssocs(hold, ASSOC_FROZEN_CONTENT, RegexQNamePattern.MATCH_ALL)).thenReturn(holds);
when(mockedRecordService.isRecord(heldContent)).thenThrow(new AccessDeniedException(""));
holdService.deleteHold(hold);
holdService.beforeDeleteNode(hold);
}
/**
* test delete hold throws exception for failed file permission check for records
* test before delete node throws exception for failed file permission check for records
*/
@Test (expected = AccessDeniedException.class)
public void testDeleteHoldThrowsExceptionForARecordWithoutFilePermission()
public void testBeforeDeleteNodeThrowsExceptionForARecordWithoutFilePermission()
{
NodeRef heldContent = generateNodeRef();
List<ChildAssociationRef> holds = createListOfHoldAssociations(heldContent);
when(mockedNodeService.getChildAssocs(hold, ASSOC_FROZEN_CONTENT, RegexQNamePattern.MATCH_ALL)).thenReturn(holds);
mockPoliciesForExistingHoldWithHeldItems(hold, heldContent);
// mocks for held record
when(mockedRecordService.isRecord(heldContent)).thenReturn(true);
when(mockedPermissionService.hasPermission(heldContent, RMPermissionModel.FILING)).thenReturn(AccessStatus.DENIED);
when(mockedNodeService.getProperty(heldContent, ContentModel.PROP_NAME)).thenReturn("foo");
holdService.deleteHold(hold);
holdService.beforeDeleteNode(hold);
}
/**
@@ -655,6 +673,18 @@ public class HoldServiceImplUnitTest extends BaseUnitTest
return holds;
}
/**
* mocks for existing hold with held items
*/
private void mockPoliciesForExistingHoldWithHeldItems(NodeRef hold, NodeRef heldContent)
{
when(mockedNodeService.exists(hold)).thenReturn(true);
when(holdService.isHold(hold)).thenReturn(true);
List<ChildAssociationRef> holds = createListOfHoldAssociations(heldContent);
when(mockedNodeService.getChildAssocs(hold, ASSOC_FROZEN_CONTENT, RegexQNamePattern.MATCH_ALL)).thenReturn(holds);
}
/**
* mocks policies for create hold
*/
@@ -50,7 +50,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.OwnableService;
import org.alfresco.util.Pair;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;