mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merge remote-tracking branch 'remotes/origin/master' into xperimental/RM-6313UpgradeRMSchedulers_remote
This commit is contained in:
@@ -662,7 +662,7 @@ public abstract class BaseAPI
|
|||||||
RETENTION_GHOST,
|
RETENTION_GHOST,
|
||||||
RETENTION_ELIGIBLE_FIRST_EVENT,
|
RETENTION_ELIGIBLE_FIRST_EVENT,
|
||||||
RETENTION_EVENTS,
|
RETENTION_EVENTS,
|
||||||
|
COMBINE_DISPOSITION_STEP_CONDITIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -674,6 +674,8 @@ public abstract class BaseAPI
|
|||||||
CUT_OFF("cutoff"),
|
CUT_OFF("cutoff"),
|
||||||
UNDO_CUT_OFF("undoCutoff"),
|
UNDO_CUT_OFF("undoCutoff"),
|
||||||
TRANSFER("transfer"),
|
TRANSFER("transfer"),
|
||||||
|
COMPLETE_EVENT("completeEvent"),
|
||||||
|
UNDO_EVENT("undoEvent"),
|
||||||
DESTROY("destroy");
|
DESTROY("destroy");
|
||||||
String action;
|
String action;
|
||||||
|
|
||||||
|
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Records Management Module
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2018 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.core.v0;
|
||||||
|
|
||||||
|
public enum RMEvents
|
||||||
|
{
|
||||||
|
ABOLISHED("abolished"),
|
||||||
|
ALL_ALLOWANCES_GRANTED_ARE_TERMINATED("all_allowances_granted_are_terminated"),
|
||||||
|
CASE_CLOSED("case_closed"),
|
||||||
|
DECLASSIFICATION_REVIEW("declassification_review"),
|
||||||
|
OBSOLETE("obsolete"),
|
||||||
|
NO_LONGER_NEEDED("no_longer_needed"),
|
||||||
|
STUDY_COMPLETE("study_complete");
|
||||||
|
private String eventName;
|
||||||
|
|
||||||
|
RMEvents(String eventName)
|
||||||
|
{
|
||||||
|
this.eventName = eventName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEventName()
|
||||||
|
{
|
||||||
|
return eventName;
|
||||||
|
}
|
||||||
|
}
|
@@ -58,6 +58,8 @@ public class FilePlanComponentFields
|
|||||||
public static final String PROPERTIES_RECORD_SEARCH_DISPOSITION_ACTION_NAME = "rma:recordSearchDispositionActionName";
|
public static final String PROPERTIES_RECORD_SEARCH_DISPOSITION_ACTION_NAME = "rma:recordSearchDispositionActionName";
|
||||||
public static final String PROPERTIES_RECORD_SEARCH_DISPOSITION_EVENTS_ELIGIBLE = "rma:recordSearchDispositionEventsEligible";
|
public static final String PROPERTIES_RECORD_SEARCH_DISPOSITION_EVENTS_ELIGIBLE = "rma:recordSearchDispositionEventsEligible";
|
||||||
public static final String PROPERTIES_RECORD_SEARCH_DISPOSITION_INSTRUCTIONS = "rma:recordSearchDispositionInstructions";
|
public static final String PROPERTIES_RECORD_SEARCH_DISPOSITION_INSTRUCTIONS = "rma:recordSearchDispositionInstructions";
|
||||||
|
public static final String PROPERTIES_DECLASSIFICATION_REVIEW_COMPLETED_BY = "rma:declassificationReviewCompletedBy";
|
||||||
|
public static final String PROPERTIES_DECLASSIFICATION_REVIEW_COMPLETED_AT = "rma:declassificationReviewCompletedAt";
|
||||||
|
|
||||||
|
|
||||||
/** File plan properties */
|
/** File plan properties */
|
||||||
|
@@ -35,6 +35,7 @@ import static org.testng.AssertJUnit.fail;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -46,6 +47,7 @@ import org.alfresco.dataprep.AlfrescoHttpClientFactory;
|
|||||||
import org.alfresco.dataprep.ContentService;
|
import org.alfresco.dataprep.ContentService;
|
||||||
import org.alfresco.dataprep.UserService;
|
import org.alfresco.dataprep.UserService;
|
||||||
import org.alfresco.rest.core.v0.BaseAPI;
|
import org.alfresco.rest.core.v0.BaseAPI;
|
||||||
|
import org.alfresco.rest.core.v0.RMEvents;
|
||||||
import org.apache.chemistry.opencmis.client.api.CmisObject;
|
import org.apache.chemistry.opencmis.client.api.CmisObject;
|
||||||
import org.apache.commons.httpclient.HttpStatus;
|
import org.apache.commons.httpclient.HttpStatus;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
@@ -325,9 +327,9 @@ public class RMRolesAndActionsAPI extends BaseAPI
|
|||||||
/**
|
/**
|
||||||
* Perform an action on the record folder
|
* Perform an action on the record folder
|
||||||
*
|
*
|
||||||
* @param user the user closing the folder
|
* @param user the user executing the action
|
||||||
* @param password the user's password
|
* @param password the user's password
|
||||||
* @param contentName the record folder name
|
* @param contentName the content name
|
||||||
* @param date the date to be updated
|
* @param date the date to be updated
|
||||||
* @return The HTTP response.
|
* @return The HTTP response.
|
||||||
*/
|
*/
|
||||||
@@ -349,6 +351,56 @@ public class RMRolesAndActionsAPI extends BaseAPI
|
|||||||
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
|
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete an event on the record/record folder
|
||||||
|
*
|
||||||
|
* @param user the user executing the action
|
||||||
|
* @param password the user's password
|
||||||
|
* @param nodeName the node name
|
||||||
|
* @param event the event to be completed
|
||||||
|
* @param date the date to be updated
|
||||||
|
* @return The HTTP response.
|
||||||
|
*/
|
||||||
|
public HttpResponse completeEvent(String user, String password, String nodeName, RMEvents event, Instant date)
|
||||||
|
{
|
||||||
|
String recNodeRef = getNodeRefSpacesStore() + contentService.getNodeRef(user, password, RM_SITE_ID, nodeName);
|
||||||
|
JSONObject requestParams = new JSONObject();
|
||||||
|
requestParams.put("name", RM_ACTIONS.COMPLETE_EVENT.getAction());
|
||||||
|
requestParams.put("nodeRef", recNodeRef);
|
||||||
|
date = (date != null) ? date : Instant.now();
|
||||||
|
String formattedDate = DateTimeFormatter.ISO_INSTANT.format(date);
|
||||||
|
requestParams.put("params", new JSONObject()
|
||||||
|
.put("eventName", event.getEventName())
|
||||||
|
.put("eventCompletedBy", user)
|
||||||
|
.put("eventCompletedAt", new JSONObject()
|
||||||
|
.put("iso8601", formattedDate)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo an event on the record/record folder
|
||||||
|
*
|
||||||
|
* @param user the user executing the action
|
||||||
|
* @param password the user's password
|
||||||
|
* @param contentName the content name
|
||||||
|
* @param event the event to be undone
|
||||||
|
* @return The HTTP response.
|
||||||
|
*/
|
||||||
|
public HttpResponse undoEvent(String user, String password, String contentName, RMEvents event)
|
||||||
|
{
|
||||||
|
String recNodeRef = getNodeRefSpacesStore() + contentService.getNodeRef(user, password, RM_SITE_ID, contentName);
|
||||||
|
JSONObject requestParams = new JSONObject();
|
||||||
|
requestParams.put("name", RM_ACTIONS.UNDO_EVENT.getAction());
|
||||||
|
requestParams.put("nodeRef", recNodeRef);
|
||||||
|
requestParams.put("params", new JSONObject()
|
||||||
|
.put("eventName", event.getEventName()));
|
||||||
|
|
||||||
|
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes every item in the given container
|
* Deletes every item in the given container
|
||||||
*
|
*
|
||||||
|
@@ -51,6 +51,8 @@ public class RecordCategoriesAPI extends BaseAPI
|
|||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RecordCategoriesAPI.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(RecordCategoriesAPI.class);
|
||||||
private static final String RM_ACTIONS_API = "{0}rma/actions/ExecutionQueue";
|
private static final String RM_ACTIONS_API = "{0}rma/actions/ExecutionQueue";
|
||||||
private static final String DISPOSITION_ACTIONS_API = "{0}node/{1}/dispositionschedule/dispositionactiondefinitions";
|
private static final String DISPOSITION_ACTIONS_API = "{0}node/{1}/dispositionschedule/dispositionactiondefinitions";
|
||||||
|
private static final String DISPOSITION_SCHEDULE_API = "{0}node/{1}/dispositionschedule";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a retention schedule for the category given as parameter
|
* Creates a retention schedule for the category given as parameter
|
||||||
@@ -71,6 +73,21 @@ public class RecordCategoriesAPI extends BaseAPI
|
|||||||
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
|
return doPostJsonRequest(user, password, SC_OK, requestParams, RM_ACTIONS_API);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the disposition schedule nodeRef
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* @param password
|
||||||
|
* @param categoryName
|
||||||
|
* @return the disposition schedule nodeRef
|
||||||
|
*/
|
||||||
|
public String getDispositionScheduleNodeRef(String user, String password, String categoryName)
|
||||||
|
{
|
||||||
|
String catNodeRef = NODE_PREFIX + getItemNodeRef(user, password, "/" + categoryName);
|
||||||
|
JSONObject dispositionSchedule = doGetRequest(user, password, MessageFormat.format(DISPOSITION_SCHEDULE_API, "{0}", catNodeRef));
|
||||||
|
return dispositionSchedule.getJSONObject("data").getString("nodeRef").replace(getNodeRefSpacesStore(), "");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets retention schedule authority and instructions, also if it is applied to records or folders
|
* Sets retention schedule authority and instructions, also if it is applied to records or folders
|
||||||
*
|
*
|
||||||
@@ -108,7 +125,12 @@ public class RecordCategoriesAPI extends BaseAPI
|
|||||||
addPropertyToRequest(requestParams, "period", properties, RETENTION_SCHEDULE.RETENTION_PERIOD);
|
addPropertyToRequest(requestParams, "period", properties, RETENTION_SCHEDULE.RETENTION_PERIOD);
|
||||||
addPropertyToRequest(requestParams, "ghostOnDestroy", properties, RETENTION_SCHEDULE.RETENTION_GHOST);
|
addPropertyToRequest(requestParams, "ghostOnDestroy", properties, RETENTION_SCHEDULE.RETENTION_GHOST);
|
||||||
addPropertyToRequest(requestParams, "periodProperty", properties, RETENTION_SCHEDULE.RETENTION_PERIOD_PROPERTY);
|
addPropertyToRequest(requestParams, "periodProperty", properties, RETENTION_SCHEDULE.RETENTION_PERIOD_PROPERTY);
|
||||||
addPropertyToRequest(requestParams, "events", properties, RETENTION_SCHEDULE.RETENTION_EVENTS);
|
String events = getPropertyValue(properties, RETENTION_SCHEDULE.RETENTION_EVENTS);
|
||||||
|
if(!events.equals(""))
|
||||||
|
{
|
||||||
|
requestParams.append("events", events);
|
||||||
|
}
|
||||||
|
addPropertyToRequest(requestParams, "combineDispositionStepConditions", properties, RETENTION_SCHEDULE.COMBINE_DISPOSITION_STEP_CONDITIONS);
|
||||||
addPropertyToRequest(requestParams, "eligibleOnFirstCompleteEvent", properties, RETENTION_SCHEDULE.RETENTION_ELIGIBLE_FIRST_EVENT);
|
addPropertyToRequest(requestParams, "eligibleOnFirstCompleteEvent", properties, RETENTION_SCHEDULE.RETENTION_ELIGIBLE_FIRST_EVENT);
|
||||||
|
|
||||||
return doPostJsonRequest(user, password, SC_OK, requestParams, MessageFormat.format(DISPOSITION_ACTIONS_API, "{0}", catNodeRef));
|
return doPostJsonRequest(user, password, SC_OK, requestParams, MessageFormat.format(DISPOSITION_ACTIONS_API, "{0}", catNodeRef));
|
||||||
|
@@ -64,8 +64,8 @@ public class SearchAPI extends BaseAPI
|
|||||||
private static final String RM_SEARCH_ENDPOINT = "{0}alfresco/s/slingshot/rmsearch/{1}?{2}";
|
private static final String RM_SEARCH_ENDPOINT = "{0}alfresco/s/slingshot/rmsearch/{1}?{2}";
|
||||||
|
|
||||||
/** RM document search filters */
|
/** RM document search filters */
|
||||||
private static final String RM_DEFAULT_RECORD_FILTERS =
|
private static final String RM_DEFAULT_NODES_FILTERS =
|
||||||
"records/true,undeclared/true,vital/false,folders/false,categories/false,frozen/false,cutoff/false";
|
"records/true,undeclared/true,vital/false,folders/{0},categories/{1},frozen/false,cutoff/false";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform search request on search endpoint as a user.
|
* Perform search request on search endpoint as a user.
|
||||||
@@ -91,6 +91,7 @@ public class SearchAPI extends BaseAPI
|
|||||||
* @param site
|
* @param site
|
||||||
* @param query
|
* @param query
|
||||||
* @param filters
|
* @param filters
|
||||||
|
* @param sortby
|
||||||
* @return search results (see API reference for more details), null for any errors
|
* @return search results (see API reference for more details), null for any errors
|
||||||
*/
|
*/
|
||||||
public JSONObject rmSearch(
|
public JSONObject rmSearch(
|
||||||
@@ -98,11 +99,16 @@ public class SearchAPI extends BaseAPI
|
|||||||
String password,
|
String password,
|
||||||
String site,
|
String site,
|
||||||
String query,
|
String query,
|
||||||
String filters)
|
String filters,
|
||||||
|
String sortby)
|
||||||
{
|
{
|
||||||
List<BasicNameValuePair> searchParameters = new ArrayList<BasicNameValuePair>();
|
List<BasicNameValuePair> searchParameters = new ArrayList<BasicNameValuePair>();
|
||||||
searchParameters.add(new BasicNameValuePair("query", query));
|
searchParameters.add(new BasicNameValuePair("query", query));
|
||||||
searchParameters.add(new BasicNameValuePair("filters", filters));
|
searchParameters.add(new BasicNameValuePair("filters", filters));
|
||||||
|
if (sortby != null)
|
||||||
|
{
|
||||||
|
searchParameters.add(new BasicNameValuePair("sortby", sortby));
|
||||||
|
}
|
||||||
|
|
||||||
String requestURL = MessageFormat.format(
|
String requestURL = MessageFormat.format(
|
||||||
RM_SEARCH_ENDPOINT,
|
RM_SEARCH_ENDPOINT,
|
||||||
@@ -114,20 +120,23 @@ public class SearchAPI extends BaseAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search as a user for records on site "rm" matching query, using SearchAPI.RM_DEFAULT_RECORD_FILTERS
|
* Search as a user for nodes on site "rm" matching query, using SearchAPI.RM_DEFAULT_RECORD_FILTERS and sorted
|
||||||
|
* by sortby
|
||||||
* <br>
|
* <br>
|
||||||
* If more fine-grained control of search parameters is required, use rmSearch() directly.
|
* If more fine-grained control of search parameters is required, use rmSearch() directly.
|
||||||
* @param username
|
* @param username
|
||||||
* @param password
|
* @param password
|
||||||
* @param query
|
* @param query
|
||||||
|
* @param sortby
|
||||||
* @return list of record names
|
* @return list of record names
|
||||||
*/
|
*/
|
||||||
public List<String> searchForRecordsAsUser(
|
public List<String> searchForRecordsAsUser(
|
||||||
String username,
|
String username, String password,
|
||||||
String password,
|
String query, String sortby,
|
||||||
String query)
|
boolean includeCategories, boolean includeFolders)
|
||||||
{
|
{
|
||||||
return getItemNames(rmSearch(username, password, "rm", query, RM_DEFAULT_RECORD_FILTERS));
|
String searchFilterParamaters = MessageFormat.format(RM_DEFAULT_NODES_FILTERS, Boolean.toString(includeFolders), Boolean.toString(includeCategories));
|
||||||
|
return getItemNames(rmSearch(username, password, "rm", query, searchFilterParamaters, sortby));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Records Management Module
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2018 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.v0.service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.alfresco.rest.core.v0.BaseAPI;
|
||||||
|
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
|
||||||
|
import org.alfresco.rest.v0.RecordCategoriesAPI;
|
||||||
|
import org.alfresco.utility.data.DataUser;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for different disposition schedule actions
|
||||||
|
*
|
||||||
|
* @author jcule
|
||||||
|
* @since 2.7.0.1
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class DispositionScheduleService extends BaseAPI
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private RecordCategoriesAPI recordCategoriesAPI;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataUser dataUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for adding a cut off after period step
|
||||||
|
*
|
||||||
|
* @param categoryName the category in whose schedule the step will be added
|
||||||
|
* @param period
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void addCutOffAfterPeriodStep(String categoryName, String period)
|
||||||
|
{
|
||||||
|
HashMap<RETENTION_SCHEDULE, String> cutOffStep = new HashMap<>();
|
||||||
|
cutOffStep.put(RETENTION_SCHEDULE.NAME, "cutoff");
|
||||||
|
cutOffStep.put(RETENTION_SCHEDULE.RETENTION_PERIOD, period);
|
||||||
|
cutOffStep.put(RETENTION_SCHEDULE.DESCRIPTION, "Cut off after a period step");
|
||||||
|
recordCategoriesAPI.addDispositionScheduleSteps(dataUser.getAdminUser().getUsername(),
|
||||||
|
dataUser.getAdminUser().getPassword(), categoryName, cutOffStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for adding a cut off after an event occurs step
|
||||||
|
*
|
||||||
|
* @param categoryName the category in whose schedule the step will be added
|
||||||
|
* @param events
|
||||||
|
*/
|
||||||
|
public void addCutOffAfterEventStep(String categoryName, String events)
|
||||||
|
{
|
||||||
|
HashMap<RETENTION_SCHEDULE, String> cutOffStep = new HashMap<>();
|
||||||
|
cutOffStep.put(RETENTION_SCHEDULE.NAME, "cutoff");
|
||||||
|
cutOffStep.put(RETENTION_SCHEDULE.RETENTION_EVENTS, events);
|
||||||
|
cutOffStep.put(RETENTION_SCHEDULE.DESCRIPTION, "Cut off after event step");
|
||||||
|
|
||||||
|
recordCategoriesAPI.addDispositionScheduleSteps(dataUser.getAdminUser().getUsername(),
|
||||||
|
dataUser.getAdminUser().getPassword(), categoryName, cutOffStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for adding an accession step
|
||||||
|
*
|
||||||
|
* @param timeOrEvent
|
||||||
|
* @param events
|
||||||
|
* @param period
|
||||||
|
* @param periodProperty
|
||||||
|
* @param combineConditions
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public void addAccessionStep(String categoryName, Boolean timeOrEvent, String events, String period, String
|
||||||
|
periodProperty, Boolean combineConditions)
|
||||||
|
{
|
||||||
|
HashMap<RETENTION_SCHEDULE, String> accessionStep = new HashMap<>();
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.NAME, "accession");
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.COMBINE_DISPOSITION_STEP_CONDITIONS, Boolean.toString(combineConditions));
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.RETENTION_PERIOD, period);
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.RETENTION_PERIOD_PROPERTY, periodProperty);
|
||||||
|
if (!timeOrEvent)
|
||||||
|
{
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.RETENTION_ELIGIBLE_FIRST_EVENT, Boolean.toString(timeOrEvent));
|
||||||
|
}
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.RETENTION_EVENTS, events);
|
||||||
|
accessionStep.put(RETENTION_SCHEDULE.DESCRIPTION,
|
||||||
|
"Accession step with time and event conditions.");
|
||||||
|
recordCategoriesAPI.addDispositionScheduleSteps(dataUser.getAdminUser().getUsername(),
|
||||||
|
dataUser.getAdminUser().getPassword(), categoryName, accessionStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to create retention schedule with general fields for the given category as admin
|
||||||
|
* and apply it to the records
|
||||||
|
*
|
||||||
|
* @param categoryName
|
||||||
|
* @param appliedToRecords
|
||||||
|
*/
|
||||||
|
public void createCategoryRetentionSchedule(String categoryName, Boolean appliedToRecords)
|
||||||
|
{
|
||||||
|
recordCategoriesAPI.createRetentionSchedule(dataUser.getAdminUser().getUsername(),
|
||||||
|
dataUser.getAdminUser().getPassword(), categoryName);
|
||||||
|
String retentionScheduleNodeRef = recordCategoriesAPI.getDispositionScheduleNodeRef(
|
||||||
|
dataUser.getAdminUser().getUsername(), dataUser.getAdminUser().getPassword(), categoryName);
|
||||||
|
|
||||||
|
HashMap<RETENTION_SCHEDULE, String> retentionScheduleGeneralFields = new HashMap<>();
|
||||||
|
retentionScheduleGeneralFields.put(RETENTION_SCHEDULE.RETENTION_AUTHORITY, "Authority");
|
||||||
|
retentionScheduleGeneralFields.put(RETENTION_SCHEDULE.RETENTION_INSTRUCTIONS, "Instructions");
|
||||||
|
recordCategoriesAPI.setRetentionScheduleGeneralFields(dataUser.getAdminUser().getUsername(),
|
||||||
|
dataUser.getAdminUser().getPassword(), retentionScheduleNodeRef, retentionScheduleGeneralFields,
|
||||||
|
appliedToRecords);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -658,7 +658,8 @@ public class BaseRMRestTest extends RestTest
|
|||||||
names.add(childNode.onModel().getName());
|
names.add(childNode.onModel().getName());
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
@@ -673,10 +674,12 @@ public class BaseRMRestTest extends RestTest
|
|||||||
*
|
*
|
||||||
* @param user
|
* @param user
|
||||||
* @param term
|
* @param term
|
||||||
|
* @param sortby
|
||||||
|
* @param expectedResults
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
|
||||||
*/
|
*/
|
||||||
public List<String> searchForRMContentAsUser(UserModel user, String term, String expectedResult) throws Exception
|
public List<String> searchForRMContentAsUser(UserModel user, String term, String sortby, boolean includeFolders,
|
||||||
|
boolean includeCategories, List<String> expectedResults)
|
||||||
{
|
{
|
||||||
List<String> results = new ArrayList<>();
|
List<String> results = new ArrayList<>();
|
||||||
// wait for solr indexing
|
// wait for solr indexing
|
||||||
@@ -684,26 +687,28 @@ public class BaseRMRestTest extends RestTest
|
|||||||
int waitInMilliSeconds = 6000;
|
int waitInMilliSeconds = 6000;
|
||||||
while (counter < 3)
|
while (counter < 3)
|
||||||
{
|
{
|
||||||
results = searchApi.searchForRecordsAsUser(user.getUsername(), user.getPassword(), term);
|
|
||||||
if ((results != null && !results.isEmpty() && results.contains(expectedResult)))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
counter++;
|
|
||||||
}
|
|
||||||
// double wait time to not overdo solr search
|
|
||||||
waitInMilliSeconds = (waitInMilliSeconds * 2);
|
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.wait(waitInMilliSeconds);
|
this.wait(waitInMilliSeconds);
|
||||||
} catch (InterruptedException e)
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
results = searchApi.searchForRecordsAsUser(user.getUsername(), user.getPassword(), term, sortby,
|
||||||
|
includeFolders, includeCategories);
|
||||||
|
if (!results.isEmpty() && results.containsAll(expectedResults))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
// double wait time to not overdo solr search
|
||||||
|
waitInMilliSeconds = (waitInMilliSeconds * 2);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@@ -11,14 +11,14 @@
|
|||||||
* Easy Access Records
|
* Easy Access Records
|
||||||
* Physical Records
|
* Physical Records
|
||||||
* Record Import and Export
|
* Record Import and Export
|
||||||
* Version Records
|
* [Version Records](./versionRecords)
|
||||||
* Retention
|
* Retention
|
||||||
* [Destruction](./destruction)
|
* [Destruction](./destruction)
|
||||||
* Retention Schedules and Events
|
* Retention Schedules and Events
|
||||||
* Transfer and Accession
|
* Transfer and Accession
|
||||||
* Security
|
* Security
|
||||||
* [Extended permission service](extendedPermissionService.md)
|
* [Extended permission service](security/extendedPermissionService.md)
|
||||||
* Roles, Capabilities and Permissions
|
* [Roles and Capabilities](security/rolesAndCapabilities.md)
|
||||||
* Discovery
|
* Discovery
|
||||||
* Governance Search
|
* Governance Search
|
||||||
* Legal Holds
|
* Legal Holds
|
||||||
@@ -27,3 +27,5 @@
|
|||||||
* Governance Rules
|
* Governance Rules
|
||||||
* Core Module Services
|
* Core Module Services
|
||||||
* [RM Patch Service](./PatchService.md)
|
* [RM Patch Service](./PatchService.md)
|
||||||
|
* Build and Release
|
||||||
|
* [Build](./build)
|
||||||
|
6
rm-community/documentation/build/README.md
Normal file
6
rm-community/documentation/build/README.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## GS Build 
|
||||||
|
|
||||||
|
Build location: https://bamboo.alfresco.com/bamboo/browse/RM (not externally accessible.)
|
||||||
|
|
||||||
|
Build Flow:
|
||||||
|

|
BIN
rm-community/documentation/build/resource/build.png
Normal file
BIN
rm-community/documentation/build/resource/build.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
66
rm-community/documentation/build/resource/build.puml
Normal file
66
rm-community/documentation/build/resource/build.puml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
@startuml
|
||||||
|
|
||||||
|
Title: Governance Services Build Pipeline (RM HEAD)
|
||||||
|
|
||||||
|
'build plans:
|
||||||
|
'Ent UI: Automated UI Tests Enterprise
|
||||||
|
'Com API: Automation Community REST API
|
||||||
|
'Ent API: Automation Enterprise REST API
|
||||||
|
'Community
|
||||||
|
'Com UI: Community Automated UI Tests
|
||||||
|
'Enterprise
|
||||||
|
'Ent L1: Enterprise Level 1 Automated UI Tests
|
||||||
|
'Ent L2: Level 2 Automated UI Tests Enterprise
|
||||||
|
'RM Benchmark Driver
|
||||||
|
|
||||||
|
|
||||||
|
start
|
||||||
|
|
||||||
|
if(Trigger) then (commit to path)
|
||||||
|
if (rm-community/*)
|
||||||
|
:Community;
|
||||||
|
fork
|
||||||
|
:Ent L1;
|
||||||
|
fork again
|
||||||
|
:Enterprise;
|
||||||
|
fork
|
||||||
|
:Ent L2;
|
||||||
|
fork again
|
||||||
|
:Ent UI;
|
||||||
|
end fork
|
||||||
|
end fork
|
||||||
|
elseif (rm-enterprise/*)
|
||||||
|
:Enterprise;
|
||||||
|
fork
|
||||||
|
:Ent L2;
|
||||||
|
fork again
|
||||||
|
:Ent UI;
|
||||||
|
end fork
|
||||||
|
elseif (rm-automation/*)
|
||||||
|
fork
|
||||||
|
:Ent L1;
|
||||||
|
fork again
|
||||||
|
:Ent L2;
|
||||||
|
fork again
|
||||||
|
:Ent UI;
|
||||||
|
end fork
|
||||||
|
stop
|
||||||
|
elseif (rm-community-rest-api/*)
|
||||||
|
:Com API;
|
||||||
|
stop
|
||||||
|
elseif (rm-enterprise-rest-api/*)
|
||||||
|
:Ent API;
|
||||||
|
stop
|
||||||
|
elseif (rm-benchmark-driver/*)
|
||||||
|
:Benchmark;
|
||||||
|
stop
|
||||||
|
else
|
||||||
|
end
|
||||||
|
endif
|
||||||
|
else (Time: 1am)
|
||||||
|
:Community UI;
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
:Release Step;
|
||||||
|
end
|
||||||
|
@enduml
|
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
41
rm-community/documentation/security/rolesAndCapabilities.md
Normal file
41
rm-community/documentation/security/rolesAndCapabilities.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
## Alfresco Governance Services' Roles and Capabilities
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
|
||||||
|
Roles and capabilities allow the GS system to provide a finer grain security evaluation, determining whether an authority has the capability to perform a perticular action on a node.
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
Roles are defined as a collection of capabilities. A capability, generally, has a one to one relationship with an action within the system.
|
||||||
|
|
||||||
|
Authorities are assigned roles. If an authority is assigned to a role then it that authority has the capabilities contained within that role, allowing them to perform the related actions.
|
||||||
|
|
||||||
|
An authority can be assigned many roles, with the associated capabilities being additive.
|
||||||
|
|
||||||
|
Capabilties are evaluated in addition to any ACLs attached to a node, but they are mutally exclusive. A authority may have the capability, but not the permissions on a node and vice versa.
|
||||||
|
|
||||||
|
### Design
|
||||||
|
|
||||||
|
Roles are implementented as groups. So for every role that is created, there is a corresponding group within the system.
|
||||||
|
|
||||||
|
Capabilities are implemented as permissions. In order add a new capability to the system, the extended RM permission model needs to be extended.
|
||||||
|
|
||||||
|
When a capability is added to a role, then the capability group is assigned the capability role on the root file plan node.
|
||||||
|
|
||||||
|
In this way the permissions of the systems roles reflect their capabilities on the file plan via the capability permissions assigned.
|
||||||
|
|
||||||
|
When an authority is assigned to a role, that authority is added as a member of the corresponding role group. In this way they inherit the capability permissions on the file plan that relate to that role group.
|
||||||
|
|
||||||
|
If a user attempts to perform an action on a records management artifact which has a related capability. Assuming the user has permission to see the artifact in the first place, then the users capability to perform the action is evaluated.
|
||||||
|
|
||||||
|
This is done by firstly determining whether the capability is relevant for this 'kind' of records management artifact. For example the addHold capability is not relevant for a record category.
|
||||||
|
|
||||||
|
Then the capability permission is evaluated by traversing to the file plan node and checking whether the current user has the capabilty permission byt virtue of it's membership of the right role group.
|
||||||
|
|
||||||
|
Finally any further conditions attached to the capability are evaluated.
|
||||||
|
|
||||||
|

|
20
rm-community/documentation/versionRecords/README.md
Normal file
20
rm-community/documentation/versionRecords/README.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
## Version Records 
|
||||||
|
|
||||||
|
### Notes:
|
||||||
|
|
||||||
|
NodesService varies depending on store. Version Service has a different service that hydrates effectively fake nodes (which contain url, version details, associations, aspects, as denormalised meta data) back into a full node
|
||||||
|
|
||||||
|
Recorded Versions take content out of version store and create a record by version store implementation extension.
|
||||||
|
|
||||||
|
Declaring record as version - standard use case is auto declaring or via records. Head version is extracted to a record, rather than a new version being created
|
||||||
|
|
||||||
|
Records are linked by association
|
||||||
|
|
||||||
|
Disposition events can be triggered automatically from versioning events.
|
||||||
|
|
||||||
|
### Diagram:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
rm-community/documentation/versionRecords/RecordedVersions.png
Normal file
BIN
rm-community/documentation/versionRecords/RecordedVersions.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
@@ -1132,6 +1132,19 @@
|
|||||||
<tokenised>false</tokenised>
|
<tokenised>false</tokenised>
|
||||||
</index>
|
</index>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="rma:declassificationReviewCompletedAt">
|
||||||
|
<type>d:date</type>
|
||||||
|
<protected>true</protected>
|
||||||
|
</property>
|
||||||
|
<property name="rma:declassificationReviewCompletedBy">
|
||||||
|
<type>d:text</type>
|
||||||
|
<protected>true</protected>
|
||||||
|
<index enabled="true">
|
||||||
|
<atomic>true</atomic>
|
||||||
|
<stored>false</stored>
|
||||||
|
<tokenised>false</tokenised>
|
||||||
|
</index>
|
||||||
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
</aspect>
|
</aspect>
|
||||||
|
|
||||||
|
@@ -468,12 +468,18 @@
|
|||||||
<property name="permissionService" ref="PermissionService" />
|
<property name="permissionService" ref="PermissionService" />
|
||||||
<property name="personService" ref="PersonService" />
|
<property name="personService" ref="PersonService" />
|
||||||
<property name="recordCategoryUtil" ref="RecordCategoryUtil" />
|
<property name="recordCategoryUtil" ref="RecordCategoryUtil" />
|
||||||
|
<property name="classificationReasonsUtil" ref="ClassificationReasonsUtil" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="RecordCategoryUtil" class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RecordCategoryUtil">
|
<bean id="RecordCategoryUtil" class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RecordCategoryUtil">
|
||||||
<property name="nodeService" ref="NodeService"/>
|
<property name="nodeService" ref="NodeService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ClassificationReasonsUtil" class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil">
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
<bean
|
<bean
|
||||||
id="webscript.org.alfresco.slingshot.rmsearch.rmsearchproperties.get"
|
id="webscript.org.alfresco.slingshot.rmsearch.rmsearchproperties.get"
|
||||||
class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RMSearchPropertiesGet"
|
class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RMSearchPropertiesGet"
|
||||||
|
@@ -35,11 +35,13 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
|
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
|
import org.alfresco.module.org_alfresco_module_rm.action.RecordsManagementAction;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails;
|
import org.alfresco.module.org_alfresco_module_rm.event.EventCompletionDetails;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
|
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
|
||||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||||
|
import org.alfresco.module.org_alfresco_module_rm.script.slingshot.RMSearchGet;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
@@ -328,6 +330,12 @@ public class DispositionActionImpl implements DispositionAction,
|
|||||||
props.put(PROP_EVENT_EXECUTION_COMPLETED_BY, completedByValue);
|
props.put(PROP_EVENT_EXECUTION_COMPLETED_BY, completedByValue);
|
||||||
services.getNodeService().setProperties(eventNodeRef, props);
|
services.getNodeService().setProperties(eventNodeRef, props);
|
||||||
|
|
||||||
|
// check a specific event from rmEventConfigBootstrap.json
|
||||||
|
if (eventName.equals("declassification_review"))
|
||||||
|
{
|
||||||
|
setDeclassificationReview(eventNodeRef, completedAtValue, completedByValue);
|
||||||
|
}
|
||||||
|
|
||||||
// Check to see if the events eligible property needs to be updated
|
// Check to see if the events eligible property needs to be updated
|
||||||
updateEventEligible();
|
updateEventEligible();
|
||||||
|
|
||||||
@@ -518,4 +526,38 @@ public class DispositionActionImpl implements DispositionAction,
|
|||||||
|
|
||||||
return eligible;
|
return eligible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets declassification review authority and date on records and record folder
|
||||||
|
*
|
||||||
|
* @param eventNodeRef Declassification review event node ref
|
||||||
|
* @param completedAtValue Declassification review authority
|
||||||
|
* @param completedByValue Declassification review date
|
||||||
|
*/
|
||||||
|
private void setDeclassificationReview(NodeRef eventNodeRef, Date completedAtValue, String completedByValue)
|
||||||
|
{
|
||||||
|
NodeRef nextDispositionActionNodeRef = services.getNodeService().getPrimaryParent(eventNodeRef).getParentRef();
|
||||||
|
NodeRef nodeRef = services.getNodeService().getPrimaryParent(nextDispositionActionNodeRef).getParentRef();
|
||||||
|
setPropsOnContent(nodeRef, completedAtValue, completedByValue);
|
||||||
|
|
||||||
|
// check if the node is a record folder then set the declassification review on the records also
|
||||||
|
if (services.getNodeService().getType(nodeRef).equals(RecordsManagementModel.TYPE_RECORD_FOLDER))
|
||||||
|
{
|
||||||
|
// get all the records inside the record folder
|
||||||
|
List<ChildAssociationRef> records = services.getNodeService().getChildAssocs(nodeRef, ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
|
||||||
|
for (ChildAssociationRef child : records)
|
||||||
|
{
|
||||||
|
NodeRef recordNodeRef = child.getChildRef();
|
||||||
|
setPropsOnContent(recordNodeRef, completedAtValue, completedByValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPropsOnContent(NodeRef nodeRef, Date completedAtValue, String completedByValue)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> nodeProps = services.getNodeService().getProperties(nodeRef);
|
||||||
|
nodeProps.put(PROP_RS_DECLASSIFICATION_REVIEW_COMPLETED_AT, completedAtValue);
|
||||||
|
nodeProps.put(PROP_RS_DECLASSIFICATION_REVIEW_COMPLETED_BY, completedByValue);
|
||||||
|
services.getNodeService().setProperties(nodeRef, nodeProps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -482,8 +482,9 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JS
|
|||||||
{
|
{
|
||||||
if(!details.isEventComplete())
|
if(!details.isEventComplete())
|
||||||
{
|
{
|
||||||
((HashMap) rmNodeValues.get("properties")).put("combineDispositionStepConditions", nodeService.getProperty(dispositionService.getNextDispositionAction(nodeRef).getDispositionActionDefinition().getNodeRef(), PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
|
HashMap properties = ((HashMap) rmNodeValues.get("properties"));
|
||||||
((HashMap) rmNodeValues.get("properties")).put("incompleteDispositionEvent", details.getEventName());
|
properties.put("combineDispositionStepConditions", nodeService.getProperty(dispositionService.getNextDispositionAction(nodeRef).getDispositionActionDefinition().getNodeRef(), PROP_COMBINE_DISPOSITION_STEP_CONDITIONS));
|
||||||
|
properties.put("incompleteDispositionEvent", details.getEventName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -240,7 +240,6 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
|||||||
QName PROP_RS_DISPOSITION_ACTION_AS_OF = QName.createQName(RM_URI, "recordSearchDispositionActionAsOf");
|
QName PROP_RS_DISPOSITION_ACTION_AS_OF = QName.createQName(RM_URI, "recordSearchDispositionActionAsOf");
|
||||||
QName PROP_RS_DISPOSITION_EVENTS_ELIGIBLE = QName.createQName(RM_URI, "recordSearchDispositionEventsEligible");
|
QName PROP_RS_DISPOSITION_EVENTS_ELIGIBLE = QName.createQName(RM_URI, "recordSearchDispositionEventsEligible");
|
||||||
QName PROP_RS_DISPOSITION_EVENTS = QName.createQName(RM_URI, "recordSearchDispositionEvents");
|
QName PROP_RS_DISPOSITION_EVENTS = QName.createQName(RM_URI, "recordSearchDispositionEvents");
|
||||||
QName PROP_DISPOSITION_EVENTS = QName.createQName(RM_URI, "dispositionEvents");
|
|
||||||
QName PROP_RS_VITAL_RECORD_REVIEW_PERIOD = QName.createQName(RM_URI, "recordSearchVitalRecordReviewPeriod");
|
QName PROP_RS_VITAL_RECORD_REVIEW_PERIOD = QName.createQName(RM_URI, "recordSearchVitalRecordReviewPeriod");
|
||||||
QName PROP_RS_VITAL_RECORD_REVIEW_PERIOD_EXPRESSION = QName.createQName(RM_URI, "recordSearchVitalRecordReviewPeriodExpression");
|
QName PROP_RS_VITAL_RECORD_REVIEW_PERIOD_EXPRESSION = QName.createQName(RM_URI, "recordSearchVitalRecordReviewPeriodExpression");
|
||||||
QName PROP_RS_DISPOSITION_PERIOD = QName.createQName(RM_URI, "recordSearchDispositionPeriod");
|
QName PROP_RS_DISPOSITION_PERIOD = QName.createQName(RM_URI, "recordSearchDispositionPeriod");
|
||||||
@@ -248,6 +247,8 @@ public interface RecordsManagementModel extends RecordsManagementCustomModel
|
|||||||
QName PROP_RS_HAS_DISPOITION_SCHEDULE = QName.createQName(RM_URI, "recordSearchHasDispositionSchedule");
|
QName PROP_RS_HAS_DISPOITION_SCHEDULE = QName.createQName(RM_URI, "recordSearchHasDispositionSchedule");
|
||||||
QName PROP_RS_DISPOITION_INSTRUCTIONS = QName.createQName(RM_URI, "recordSearchDispositionInstructions");
|
QName PROP_RS_DISPOITION_INSTRUCTIONS = QName.createQName(RM_URI, "recordSearchDispositionInstructions");
|
||||||
QName PROP_RS_DISPOITION_AUTHORITY = QName.createQName(RM_URI, "recordSearchDispositionAuthority");
|
QName PROP_RS_DISPOITION_AUTHORITY = QName.createQName(RM_URI, "recordSearchDispositionAuthority");
|
||||||
|
QName PROP_RS_DECLASSIFICATION_REVIEW_COMPLETED_AT = QName.createQName(RM_URI, "declassificationReviewCompletedAt");
|
||||||
|
QName PROP_RS_DECLASSIFICATION_REVIEW_COMPLETED_BY = QName.createQName(RM_URI, "declassificationReviewCompletedBy");
|
||||||
/** @depreacted as of 2.2, because disposable items can now be in multiple holds */
|
/** @depreacted as of 2.2, because disposable items can now be in multiple holds */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
QName PROP_RS_HOLD_REASON = QName.createQName(RM_URI, "recordSearchHoldReason");
|
QName PROP_RS_HOLD_REASON = QName.createQName(RM_URI, "recordSearchHoldReason");
|
||||||
|
@@ -51,6 +51,8 @@ import org.springframework.extensions.webscripts.WebScriptRequest;
|
|||||||
*/
|
*/
|
||||||
public class DispositionAbstractBase extends AbstractRmWebScript
|
public class DispositionAbstractBase extends AbstractRmWebScript
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public final static String COMBINE_DISPOSITION_STEP_CONDITIONS = "combineDispositionStepConditions";
|
||||||
/**
|
/**
|
||||||
* Parses the request and providing it's valid returns the DispositionSchedule object.
|
* Parses the request and providing it's valid returns the DispositionSchedule object.
|
||||||
*
|
*
|
||||||
|
@@ -133,10 +133,10 @@ public class DispositionActionDefinitionPost extends DispositionAbstractBase
|
|||||||
json.getBoolean("eligibleOnFirstCompleteEvent") ? "or" : "and");
|
json.getBoolean("eligibleOnFirstCompleteEvent") ? "or" : "and");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.has("combineDispositionStepConditions"))
|
if (json.has(COMBINE_DISPOSITION_STEP_CONDITIONS))
|
||||||
{
|
{
|
||||||
props.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS,
|
props.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS,
|
||||||
json.getBoolean("combineDispositionStepConditions"));
|
json.getBoolean(COMBINE_DISPOSITION_STEP_CONDITIONS));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.has("location"))
|
if (json.has("location"))
|
||||||
|
@@ -131,10 +131,10 @@ public class DispositionActionDefinitionPut extends DispositionAbstractBase
|
|||||||
json.getBoolean("eligibleOnFirstCompleteEvent") ? "or" : "and");
|
json.getBoolean("eligibleOnFirstCompleteEvent") ? "or" : "and");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.has("combineDispositionStepConditions"))
|
if (json.has(COMBINE_DISPOSITION_STEP_CONDITIONS))
|
||||||
{
|
{
|
||||||
props.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS,
|
props.put(RecordsManagementModel.PROP_COMBINE_DISPOSITION_STEP_CONDITIONS,
|
||||||
json.getBoolean("combineDispositionStepConditions"));
|
json.getBoolean(COMBINE_DISPOSITION_STEP_CONDITIONS));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.has("location"))
|
if (json.has("location"))
|
||||||
|
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Records Management Module
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2018 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.script.slingshot;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.PROP_NAME;
|
||||||
|
import static org.alfresco.service.namespace.QName.createQName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to replace the plain text classification reason id with the correct nodeRef during record search
|
||||||
|
* @author Ross Gale
|
||||||
|
* @since 2.7
|
||||||
|
*/
|
||||||
|
public class ClassificationReasonsUtil extends SearchUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final String CR_URI = "http://www.alfresco.org/model/securitymarks/1.0";
|
||||||
|
public static final QName CLASSIFICATION_REASONS_CONTAINER = createQName(CR_URI,"classificationReasonsContainer");
|
||||||
|
public static final QName PROP_CLASSIFICATION_REASON_CODE = createQName(CR_URI, "classificationReasonCode");
|
||||||
|
public static final String REASONS_KEY = "clf:classificationReasons:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace plain text reason id with nodeRef
|
||||||
|
* @param searchQuery String e.g. clf:classificationReasons:1.4(a)
|
||||||
|
* @return String e.g. clf:classificationReasons:5cc6d344-fa94-4370-9c81-d947b7e8f2ac
|
||||||
|
*/
|
||||||
|
public String replaceReasonWithNodeRef(String searchQuery)
|
||||||
|
{
|
||||||
|
List<String> queries = new ArrayList<>(Arrays.asList(searchQuery.split(" ")));
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (String queryToEdit : queries)
|
||||||
|
{
|
||||||
|
if(queryToEdit.contains(REASONS_KEY))
|
||||||
|
{
|
||||||
|
for (String reasonId : retrieveAllNodeIds(getRootContainer(CLASSIFICATION_REASONS_CONTAINER)))
|
||||||
|
{
|
||||||
|
NodeRef reasonNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, reasonId);
|
||||||
|
Map<QName, Serializable> properties = nodeService.getProperties(reasonNodeRef);
|
||||||
|
if (queryToEdit.equals(REASONS_KEY + properties.get(PROP_CLASSIFICATION_REASON_CODE).toString()) ||
|
||||||
|
queryToEdit.equals(REASONS_KEY +"\""+ properties.get(PROP_CLASSIFICATION_REASON_CODE).toString() + "\""))
|
||||||
|
{
|
||||||
|
queryToEdit = REASONS_KEY + properties.get(PROP_NAME).toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stringBuilder.append(queryToEdit).append(" ");
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
package org.alfresco.module.org_alfresco_module_rm.script.slingshot;
|
package org.alfresco.module.org_alfresco_module_rm.script.slingshot;
|
||||||
|
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil.REASONS_KEY;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
@@ -103,6 +105,9 @@ public class RMSearchGet extends DeclarativeWebScript
|
|||||||
/** Utility class for record categories */
|
/** Utility class for record categories */
|
||||||
private RecordCategoryUtil recordCategoryUtil;
|
private RecordCategoryUtil recordCategoryUtil;
|
||||||
|
|
||||||
|
/** Utility class for classification reasons (enterprise only) */
|
||||||
|
private ClassificationReasonsUtil classificationReasonsUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param recordsManagementSearchService records management search service
|
* @param recordsManagementSearchService records management search service
|
||||||
*/
|
*/
|
||||||
@@ -159,6 +164,11 @@ public class RMSearchGet extends DeclarativeWebScript
|
|||||||
this.recordCategoryUtil = recordCategoryUtil;
|
this.recordCategoryUtil = recordCategoryUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setClassificationReasonsUtil(ClassificationReasonsUtil classificationReasonsUtil)
|
||||||
|
{
|
||||||
|
this.classificationReasonsUtil = classificationReasonsUtil;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param personService person service
|
* @param personService person service
|
||||||
*/
|
*/
|
||||||
@@ -198,6 +208,12 @@ public class RMSearchGet extends DeclarativeWebScript
|
|||||||
String filters = req.getParameter(PARAM_FILTERS);
|
String filters = req.getParameter(PARAM_FILTERS);
|
||||||
// TODO this is optional
|
// TODO this is optional
|
||||||
|
|
||||||
|
//Replace any plain text reason ids with the appropriate node reference
|
||||||
|
if(query.contains(REASONS_KEY))
|
||||||
|
{
|
||||||
|
query = classificationReasonsUtil.replaceReasonWithNodeRef(query);
|
||||||
|
}
|
||||||
|
|
||||||
// Convert into a rm search parameter object
|
// Convert into a rm search parameter object
|
||||||
RecordsManagementSearchParameters searchParameters =
|
RecordsManagementSearchParameters searchParameters =
|
||||||
SavedSearchDetailsCompatibility.createSearchParameters(filters, new String[]{",", "/"}, sortby, namespaceService);
|
SavedSearchDetailsCompatibility.createSearchParameters(filters, new String[]{",", "/"}, sortby, namespaceService);
|
||||||
|
@@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Records Management Module
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2018 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.script.slingshot;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.ASSOC_CHILDREN;
|
||||||
|
import static org.alfresco.model.ContentModel.TYPE_CONTAINER;
|
||||||
|
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent class for records search utilities
|
||||||
|
*
|
||||||
|
* @author Ross Gale
|
||||||
|
* @since 2.7
|
||||||
|
*/
|
||||||
|
public class SearchUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Node service
|
||||||
|
*/
|
||||||
|
protected NodeService nodeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setter for node service
|
||||||
|
*
|
||||||
|
* @param nodeService Node service
|
||||||
|
*/
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use a container node ref and return the nodeIds of the contents
|
||||||
|
*
|
||||||
|
* @param nodeRef container
|
||||||
|
* @return list of nodeIds
|
||||||
|
*/
|
||||||
|
protected Set<String> retrieveAllNodeIds(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
List<ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(nodeRef);
|
||||||
|
return childAssocRefs.stream().map(assoc -> assoc.getChildRef().getId()).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get the classification reason root container.
|
||||||
|
* The method creates the container if it doesn't already exist.
|
||||||
|
*
|
||||||
|
* @return reference to the classification reason root container
|
||||||
|
*/
|
||||||
|
protected NodeRef getRootContainer(QName container)
|
||||||
|
{
|
||||||
|
NodeRef rootNodeRef = nodeService.getRootNode(STORE_REF_WORKSPACE_SPACESSTORE);
|
||||||
|
List<ChildAssociationRef> assocRefs = nodeService.getChildAssocs(rootNodeRef, ASSOC_CHILDREN, container);
|
||||||
|
|
||||||
|
if (assocRefs.isEmpty())
|
||||||
|
{
|
||||||
|
return nodeService.createNode(rootNodeRef, ASSOC_CHILDREN, container, TYPE_CONTAINER).getChildRef();
|
||||||
|
}
|
||||||
|
else if (assocRefs.size() != 1)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Only one container is allowed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return assocRefs.iterator().next().getChildRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Records Management Module
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2018 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.script.slingshot;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.ASSOC_CHILDREN;
|
||||||
|
import static org.alfresco.model.ContentModel.PROP_NAME;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil.CLASSIFICATION_REASONS_CONTAINER;
|
||||||
|
import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil.PROP_CLASSIFICATION_REASON_CODE;
|
||||||
|
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ross Gale
|
||||||
|
* @since 2.7
|
||||||
|
*/
|
||||||
|
public class ClassificationReasonsUtilUnitTest
|
||||||
|
{
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private NodeService nodeService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ChildAssociationRef childAssociationRef;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ChildAssociationRef reason;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Map<QName, Serializable> properties;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private ClassificationReasonsUtil classificationReasonsUtil;
|
||||||
|
|
||||||
|
private NodeRef childNodeRef;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp()
|
||||||
|
{
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
NodeRef rootNodeRef = new NodeRef("workspace://SpacesStore/rootNodeRef");
|
||||||
|
NodeRef containerNodeRef = new NodeRef("workspace://SpacesStore/containerNodeRef");
|
||||||
|
childNodeRef = new NodeRef("workspace://SpacesStore/childNodeRef");
|
||||||
|
List<ChildAssociationRef> assocRefs = new ArrayList<>();
|
||||||
|
List<ChildAssociationRef> childAssocRefs = new ArrayList<>();
|
||||||
|
assocRefs.add(childAssociationRef);
|
||||||
|
childAssocRefs.add(reason);
|
||||||
|
when(reason.getChildRef()).thenReturn(childNodeRef);
|
||||||
|
when(nodeService.getRootNode(STORE_REF_WORKSPACE_SPACESSTORE)).thenReturn(rootNodeRef);
|
||||||
|
when(nodeService.getChildAssocs(rootNodeRef, ASSOC_CHILDREN, CLASSIFICATION_REASONS_CONTAINER)).thenReturn(assocRefs);
|
||||||
|
when(childAssociationRef.getChildRef()).thenReturn(containerNodeRef);
|
||||||
|
when(nodeService.getChildAssocs(containerNodeRef)).thenReturn(childAssocRefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check no modifications are made to non matching parts of the query string
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testNoChangeMadeToStringIfKeyNotFound()
|
||||||
|
{
|
||||||
|
String stringToTest = "noChangeMadeToString";
|
||||||
|
assertEquals("Change made to string",stringToTest, classificationReasonsUtil.replaceReasonWithNodeRef(stringToTest).trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check no modifications made if the plain text parameter doesn't have a stored match
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testNoChangeMadeToStringIfMatchNotFound()
|
||||||
|
{
|
||||||
|
when(nodeService.getProperties(childNodeRef)).thenReturn(properties);
|
||||||
|
when(properties.get(PROP_CLASSIFICATION_REASON_CODE)).thenReturn("not a match!");
|
||||||
|
String stringToTest = "clf:classificationReasons:noChangeMadeToString";
|
||||||
|
assertEquals("Change made to string", stringToTest, classificationReasonsUtil.replaceReasonWithNodeRef(stringToTest).trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the query is updated correctly when a match is found
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testChangeMadeToStringIfMatchFound()
|
||||||
|
{
|
||||||
|
when(nodeService.getProperties(childNodeRef)).thenReturn(properties);
|
||||||
|
when(properties.get(PROP_CLASSIFICATION_REASON_CODE)).thenReturn("stringToChange");
|
||||||
|
when(properties.get(PROP_NAME)).thenReturn("newString");
|
||||||
|
String stringToTest = "clf:classificationReasons:stringToChange";
|
||||||
|
assertEquals("No change made to string", "clf:classificationReasons:newString", classificationReasonsUtil.replaceReasonWithNodeRef(stringToTest).trim());
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user