Merge branch 'feature/RM-4639_REST_API_Refactoring_2' into 'master'

Feature/rm 4639 rest api refactoring 2

See merge request !209
This commit is contained in:
Ramona Popa
2017-04-12 07:36:12 +01:00
154 changed files with 18151 additions and 7134 deletions

View File

@@ -45,11 +45,6 @@
</build>
<dependencies>
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.alfresco.tas</groupId>
<artifactId>restapi-test</artifactId>
@@ -61,16 +56,17 @@
<version>${tas.restapi.version}</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
<!-- FIXME: Remove this dependency once RMUserAPI.java has been refactored -->
<dependency>
<groupId>org.jglue.fluent-json</groupId>
<artifactId>fluent-json</artifactId>
<version>${fluent.json.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@@ -30,12 +30,15 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import lombok.Getter;
/**
* Extends {@link RestProperties} to be able to change/add properties
*
* @author Tuna Aksoy
* @since 2.6
*/
@Getter
@Configuration
@PropertySource(value = {"classpath:default.properties", "classpath:config.properties"})
@PropertySource(value = "classpath:module.properties", ignoreResourceNotFound = true)
@@ -53,36 +56,4 @@ public class RMRestProperties extends RestProperties
@Value ("${rest.rmPath}")
private String restRmPath;
/**
* @return the scheme
*/
public String getScheme()
{
return this.scheme;
}
/**
* @return the server
*/
public String getServer()
{
return this.server;
}
/**
* @return the port
*/
public String getPort()
{
return this.port;
}
/**
* @return the restRmPath
*/
public String getRestRmPath()
{
return this.restRmPath;
}
}

View File

@@ -34,15 +34,17 @@ import org.alfresco.rest.model.RestHtmlResponse;
import org.alfresco.rest.model.RestSiteModel;
import org.alfresco.rest.model.RestSiteModelsCollection;
import org.alfresco.rest.requests.coreAPI.RestCoreAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RestIGCoreAPI;
import org.alfresco.rest.rm.community.requests.gscore.GSCoreAPI;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import lombok.Getter;
/**
* Extends {@link RestWrapper} in order to call IG APIs with our own properties
* Extends {@link RestWrapper} in order to call GS APIs with our own properties
*
* @author Tuna Aksoy
* @since 2.6
@@ -54,12 +56,14 @@ public class RMRestWrapper
/** The class that wraps the ReST APIs from core. */
@Autowired
private RestWrapper restWrapper;
@Autowired
@Getter
private RMRestProperties rmRestProperties;
public RestIGCoreAPI withIGCoreAPI()
public GSCoreAPI withGSCoreAPI()
{
return new RestIGCoreAPI(this, rmRestProperties);
return new GSCoreAPI(this, getRmRestProperties());
}
/** Get the core class that wraps the ReST APIs. */
@@ -159,12 +163,4 @@ public class RMRestWrapper
{
return restWrapper.processHtmlResponse(simpleRequest);
}
/**
* @return the rmRestProperties
*/
public RMRestProperties getRmRestProperties()
{
return this.rmRestProperties;
}
}

View File

@@ -26,16 +26,24 @@
*/
package org.alfresco.rest.core;
import static lombok.AccessLevel.PROTECTED;
import javax.annotation.Resource;
import org.alfresco.rest.requests.Node;
import org.alfresco.rest.requests.coreAPI.RestCoreAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilesAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RMUserAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RecordsAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RestIGCoreAPI;
import org.alfresco.rest.rm.community.requests.gscore.GSCoreAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.FilesAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMUserAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
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.TransferAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
import org.alfresco.utility.data.DataUser;
import org.alfresco.utility.model.RepoTestModel;
import org.alfresco.utility.model.UserModel;
@@ -43,8 +51,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import lombok.Getter;
import lombok.Setter;
/**
* REST API Factory Implementation
* REST API Factory which provides access to the APIs
*
* @author Tuna Aksoy
* @since 2.6
@@ -54,93 +65,143 @@ import org.springframework.stereotype.Service;
public class RestAPIFactory
{
@Autowired
@Getter (value = PROTECTED)
private DataUser dataUser;
@Resource(name = "RMRestWrapper")
@Getter
@Setter
private RMRestWrapper rmRestWrapper;
/**
* @return the rmRestWrapper
*/
public RMRestWrapper getRmRestWrapper()
private GSCoreAPI getGSCoreAPI(UserModel userModel)
{
return this.rmRestWrapper;
getRmRestWrapper().authenticateUser(userModel != null ? userModel : getDataUser().getAdminUser());
return getRmRestWrapper().withGSCoreAPI();
}
public void setRmRestWrapper(RMRestWrapper rmRestWrapper)
private RestCoreAPI getCoreAPI(UserModel userModel)
{
this.rmRestWrapper = rmRestWrapper;
}
private RestIGCoreAPI getRestIGCoreAPI(UserModel userModel)
{
getRmRestWrapper().authenticateUser(userModel != null ? userModel : dataUser.getAdminUser());
return getRmRestWrapper().withIGCoreAPI();
}
private RestCoreAPI getRestCoreAPI(UserModel userModel)
{
getRmRestWrapper().authenticateUser(userModel != null ? userModel : dataUser.getAdminUser());
getRmRestWrapper().authenticateUser(userModel != null ? userModel : getDataUser().getAdminUser());
return getRmRestWrapper().withCoreAPI();
}
public Node getNodeAPI(RepoTestModel model) throws Exception
{
return getRestCoreAPI(null).usingNode(model);
return getCoreAPI(null).usingNode(model);
}
public Node getNodeAPI(UserModel userModel, RepoTestModel model) throws Exception
{
return getRestCoreAPI(userModel).usingNode(model);
return getCoreAPI(userModel).usingNode(model);
}
public RMSiteAPI getRMSiteAPI()
{
return getRestIGCoreAPI(null).usingRMSite();
return getGSCoreAPI(null).usingRMSite();
}
public RMSiteAPI getRMSiteAPI(UserModel userModel)
{
return getRestIGCoreAPI(userModel).usingRMSite();
return getGSCoreAPI(userModel).usingRMSite();
}
public FilePlanComponentAPI getFilePlanComponentsAPI()
public FilePlanAPI getFilePlansAPI()
{
return getRestIGCoreAPI(null).usingFilePlanComponents();
return getGSCoreAPI(null).usingFilePlans();
}
public FilePlanComponentAPI getFilePlanComponentsAPI(UserModel userModel)
public FilePlanAPI getFilePlansAPI(UserModel userModel)
{
return getRestIGCoreAPI(userModel).usingFilePlanComponents();
return getGSCoreAPI(userModel).usingFilePlans();
}
public RecordCategoryAPI getRecordCategoryAPI()
{
return getGSCoreAPI(null).usingRecordCategory();
}
public RecordCategoryAPI getRecordCategoryAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingRecordCategory();
}
public RecordFolderAPI getRecordFolderAPI()
{
return getGSCoreAPI(null).usingRecordFolder();
}
public RecordFolderAPI getRecordFolderAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingRecordFolder();
}
public RecordsAPI getRecordsAPI()
{
return getRestIGCoreAPI(null).usingRecords();
return getGSCoreAPI(null).usingRecords();
}
public RecordsAPI getRecordsAPI(UserModel userModel)
{
return getRestIGCoreAPI(userModel).usingRecords();
return getGSCoreAPI(userModel).usingRecords();
}
public FilesAPI getFilesAPI()
{
return getRestIGCoreAPI(null).usingFiles();
return getGSCoreAPI(null).usingFiles();
}
public FilesAPI getFilesAPI(UserModel userModel)
{
return getRestIGCoreAPI(userModel).usingFiles();
return getGSCoreAPI(userModel).usingFiles();
}
public TransferContainerAPI getTransferContainerAPI()
{
return getGSCoreAPI(null).usingTransferContainer();
}
public TransferContainerAPI getTransferContainerAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingTransferContainer();
}
public TransferAPI getTransferAPI()
{
return getGSCoreAPI(null).usingTransfer();
}
public TransferAPI getTransferAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingTransfer();
}
public RMUserAPI getRMUserAPI()
{
return getRestIGCoreAPI(null).usingRMUser();
return getGSCoreAPI(null).usingRMUser();
}
public RMUserAPI getRMUserAPI(UserModel userModel)
{
return getRestIGCoreAPI(userModel).usingRMUser();
return getGSCoreAPI(userModel).usingRMUser();
}
public UnfiledContainerAPI getUnfiledContainersAPI()
{
return getGSCoreAPI(null).usingUnfiledContainers();
}
public UnfiledContainerAPI getUnfiledContainersAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingUnfiledContainers();
}
public UnfiledRecordFolderAPI getUnfiledRecordFoldersAPI()
{
return getGSCoreAPI(null).usingUnfiledRecordFolder();
}
public UnfiledRecordFolderAPI getUnfiledRecordFoldersAPI(UserModel userModel)
{
return getGSCoreAPI(userModel).usingUnfiledRecordFolder();
}
}

View File

@@ -24,7 +24,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.common;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -41,8 +43,11 @@ import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponentIdNamePair
public class IdNamePair
{
public String id;
public String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private String name;
}

View File

@@ -24,25 +24,26 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.common;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.EqualsAndHashCode;
/**
* POJO for file plan component created by object
* POJO for owner parameter
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponentUserInfo
@EqualsAndHashCode(callSuper = true)
//@NoArgsConstructor
//@AllArgsConstructor
public class Owner extends TestModel
{
private String id;
private String displayName;
}

View File

@@ -24,31 +24,39 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.common;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for FilePlanComponent path parameter
* POJO for path parameter
*
* @author Kristijan Conkas
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilePlanComponentPath
public class Path extends TestModel
{
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private Boolean isComplete;
private List<FilePlanComponentIdNamePair> elements;
@JsonProperty (required = true)
private List<IdNamePair> elements;
}

View File

@@ -24,7 +24,9 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.common;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -32,7 +34,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
/**
* POJO for the file plan component review period
* POJO for the review period parameter
*
* @author Rodica Sutu
* @since 2.6
@@ -41,8 +43,11 @@ import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponentReviewPeriod
public class ReviewPeriod
{
@JsonProperty (required = true)
private String periodType;
@JsonProperty (required = true)
private String expression;
}

View File

@@ -0,0 +1,99 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.fileplan;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for file plan
*
* @author Ramona Popa
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class FilePlan extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private FilePlanProperties properties;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
}

View File

@@ -0,0 +1,78 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.fileplan;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_COMPONENT_ID;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_COUNT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for file plan properties
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_COMPONENT_ID)
private String componentd;
@JsonProperty (required = true, value = PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
/************************/
/** Optional parameters */
/************************/
@JsonProperty (PROPERTIES_COUNT)
private Integer count;
}

View File

@@ -37,5 +37,4 @@ public class FilePlanComponentAlias
public static final String FILE_PLAN_ALIAS = "-filePlan-";
public static final String TRANSFERS_ALIAS = "-transfers-";
public static final String UNFILED_RECORDS_CONTAINER_ALIAS = "-unfiled-";
public static final String HOLDS_ALIAS = "-holds-";
}

View File

@@ -34,6 +34,6 @@ package org.alfresco.rest.rm.community.model.fileplancomponents;
*/
public class FilePlanComponentAspects
{
// aspect present on closed records
public static final String ASPECTS_CLOSED_RECORD = "rma:declaredRecord";
// aspect present on completed records
public static final String ASPECTS_COMPLETED_RECORD = "rma:declaredRecord";
}

View File

@@ -34,33 +34,85 @@ package org.alfresco.rest.rm.community.model.fileplancomponents;
*/
public class FilePlanComponentFields
{
public static final String NAME = "name";
public static final String NODE_TYPE = "nodeType";
public static final String NODE_PARENT_ID = "parentId";
public static final String ENTRY = "entry";
public static final String PROPERTIES = "properties";
/** Common properties for file plans, record categories, record folders and records */
public static final String PROPERTIES_ROOT_NODE_REF = "rma:rootNodeRef";
public static final String PROPERTIES_IDENTIFIER = "rma:identifier";
public static final String PROPERTIES_ID_IS_TEMPORARILY_EDITABLE = "rma:idIsTemporarilyEditable";
/** Common properties for record categories, record folders and records */
// Non-electronic record properties
public static final String PROPERTIES_TITLE = "cm:title";
public static final String PROPERTIES_RECORD_ID = "rma:identifier";
public static final String PROPERTIES_VITAL_RECORD_INDICATOR = "rma:vitalRecordIndicator";
public static final String PROPERTIES_HOLD_REASON = "rma:holdReason";
public static final String PROPERTIES_DESCRIPTION = "cm:description";
public static final String PROPERTIES_SUPPLEMENTAL_MARKING_LIST = "rmc:supplementalMarkingList";
public static final String ALLOWABLE_OPERATIONS = "allowableOperations";
public static final String IS_CLOSED = "isClosed";
/** Common properties for record categories and record folders **/
public static final String PROPERTIES_VITAL_RECORD_INDICATOR = "rma:vitalRecordIndicator";
public static final String PROPERTIES_REVIEW_PERIOD = "rma:reviewPeriod";
public static final String PROPERTIES_LOCATION = "rma:location";
public static final String PROPERTIES_OWNER = "cm:owner";
/** Common properties for record folders and records */
public static final String PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE = "rma:recordSearchHasDispositionSchedule";
/** File plan properties */
public static final String PROPERTIES_COMPONENT_ID = "st:componentId";
public static final String PROPERTIES_COUNT = "rma:count";
/** Record category properties */
// All fields are shared with record folders
/** Record folder properties */
public static final String PROPERTIES_IS_CLOSED = "rma:isClosed"; // not to be confused with IS_CLOSED!
public static final String IS_COMPLETED = "isCompleted";
// for non-electronic records
public static final String PROPERTIES_BOX = "rma:box";
public static final String PROPERTIES_FILE = "rma:file";
public static final String PROPERTIES_NUMBER_OF_COPIES = "rma:numberOfCopies";
public static final String PROPERTIES_PHYSICAL_SIZE = "rma:physicalSize";
public static final String PROPERTIES_HELD_CHILDREN_COUNT = "rma:heldChildrenCount";
public static final String PROPERTIES_LOCATION = "rma:location";
public static final String PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD = "rma:recordSearchVitalRecordReviewPeriod";
public static final String PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD_EXPRESSION = "rma:recordSearchVitalRecordReviewPeriodExpression";
/** Record properties */
public static final String PROPERTIES_DATE_FILED = "rma:dateFiled";
public static final String PROPERTIES_ORIGINAL_NAME = "rma:origionalName";
/** Electronic record properties */
public static final String PROPERTIES_VERSION_TYPE = "cm:versionType";
public static final String PROPERTIES_VERSION_LABEL = "cm:versionLabel";
public static final String PROPERTIES_DATE_TIME_ORIGINAL = "exif:dateTimeOriginal";
public static final String PROPERTIES_EXPOSURE_TIME = "exif:exposureTime";
public static final String PROPERTIES_FLASH = "exif:flash";
public static final String PROPERTIES_F_NUMBER = "exif:fNumber";
public static final String PROPERTIES_FOCAL_LENGTH = "exif:focalLength";
public static final String PROPERTIES_ISO_SPEED_RATINGS = "exif:isoSpeedRatings";
public static final String PROPERTIES_MANUFACTURER = "exif:manufacturer";
public static final String PROPERTIES_MODEL = "exif:model";
public static final String PROPERTIES_ORIENTATION = "exif:orientation";
public static final String PROPERTIES_PIXEL_X_DIMENSION = "exif:pixelXDimension";
public static final String PROPERTIES_PIXEL_Y_DIMENSION = "exif:pixelYDimension";
public static final String PROPERTIES_RESOLUTION_UNIT = "exif:resolutionUnit";
public static final String PROPERTIES_SOFTWARE = "exif:software";
public static final String PROPERTIES_X_RESOLUTION = "exif:xResolution";
public static final String PROPERTIES_Y_RESOLUTION = "exif:yResolution";
public static final String PROPERTIES_RECORD_ORIGINATING_LOCATION = "rma:recordOriginatingLocation";
public static final String PROPERTIES_RECORD_ORIGINATING_USER_ID = "rma:recordOriginatingUserId";
public static final String PROPERTIES_RECORD_ORIGINATING_CREATION_DATE = "rma:recordOriginatingCreationDate";
/** Non-electronic record properties */
public static final String PROPERTIES_SHELF = "rma:shelf";
public static final String PROPERTIES_STORAGE_LOCATION = "rma:storageLocation";
public static final String PROPERTIES_FILE = "rma:file";
public static final String PROPERTIES_BOX = "rma:box";
public static final String PROPERTIES_NUMBER_OF_COPIES = "rma:numberOfCopies";
public static final String PROPERTIES_PHYSICAL_SIZE = "rma:physicalSize";
//RelativePath specifies the container structure to create relative to the nodeId.
/** Transfer properties */
public static final String PROPERTIES_PDF_INDICATOR = "rma:transferPDFIndicator";
public static final String PROPERTIES_TRANSFER_LOCATION = "rma:transferLocation";
public static final String PROPERTIES_ACCESSION_INDICATOR = "rma:transferAccessionIndicator";
/** Parameters */
public static final String RELATIVE_PATH = "relativePath";
public static final String INCLUDE = "include";
/** Include options */
public static final String ALLOWABLE_OPERATIONS = "allowableOperations";
public static final String IS_CLOSED = "isClosed";
public static final String IS_COMPLETED = "isCompleted";
public static final String CONTENT = "content";
public static final String PATH = "path";
}

View File

@@ -38,9 +38,7 @@ public class FilePlanComponentType
public static final String RECORD_CATEGORY_TYPE = "rma:recordCategory";
public static final String RECORD_FOLDER_TYPE = "rma:recordFolder";
public static final String RECORD_TYPE = "rma:record"; // generic record type
public static final String HOLD_TYPE = "rma:hold";
public static final String UNFILED_RECORD_FOLDER_TYPE = "rma:unfiledRecordFolder";
public static final String HOLD_CONTAINER_TYPE = "rma:holdContainer";
public static final String TRANSFER_TYPE = "rma:transfer";
public static final String TRANSFER_CONTAINER_TYPE = "rma:transferContainer";
public static final String UNFILED_CONTAINER_TYPE = "rma:unfiledRecordContainer";

View File

@@ -0,0 +1,103 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.record;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class Record extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private RecordContent content;
@JsonProperty
private Boolean isCompleted;
@JsonProperty
private RecordProperties properties;
@JsonProperty
private List<String> aspectNames;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
}

View File

@@ -24,16 +24,17 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.record;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.alfresco.utility.model.TestModel;
/**
* POJO for File records
@@ -43,14 +44,11 @@ import org.alfresco.utility.model.TestModel;
*/
@Builder
@Data
@EqualsAndHashCode (callSuper = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordBodyFile extends TestModel
{
@JsonProperty
private String targetParentId;
@JsonProperty
private String relativePath;
}

View File

@@ -24,30 +24,32 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.record;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for FilePlanComponent content field
* POJO for record content field
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponentContent
public class RecordContent extends TestModel
{
@JsonProperty (required = true)
private String encoding;
@JsonProperty (required = true)
private String mimeType;
@@ -56,4 +58,7 @@ public class FilePlanComponentContent
@JsonProperty (required = true)
private Integer sizeInBytes;
@JsonProperty (required = true)
private String encoding;
}

View File

@@ -0,0 +1,203 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.record;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_BOX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DATE_FILED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DATE_TIME_ORIGINAL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_EXPOSURE_TIME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FILE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FLASH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FOCAL_LENGTH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_F_NUMBER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ISO_SPEED_RATINGS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_MANUFACTURER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_MODEL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_NUMBER_OF_COPIES;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ORIENTATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ORIGINAL_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PHYSICAL_SIZE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PIXEL_X_DIMENSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PIXEL_Y_DIMENSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RESOLUTION_UNIT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SHELF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SOFTWARE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_STORAGE_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VERSION_LABEL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VERSION_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_X_RESOLUTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_Y_RESOLUTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_ORIGINATING_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_ORIGINATING_USER_ID;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_ORIGINATING_CREATION_DATE;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record properties
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (required = true, value = PROPERTIES_DATE_FILED)
private String dateField;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE)
private Boolean recordSearchHasDispositionSchedule;
@JsonProperty (required = true, value = PROPERTIES_ORIGINAL_NAME)
private String originalName;
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
/*********************************/
/** Electronic record parameters */
/*********************************/
@JsonProperty (PROPERTIES_VERSION_TYPE)
private String versionType;
@JsonProperty (PROPERTIES_VERSION_LABEL)
private String versionLabel;
@JsonProperty (PROPERTIES_DATE_TIME_ORIGINAL)
private String dateTimeOriginal;
@JsonProperty (PROPERTIES_EXPOSURE_TIME)
private Double exposureTime;
@JsonProperty (PROPERTIES_FLASH)
private Boolean flash;
@JsonProperty (PROPERTIES_F_NUMBER)
private Double fNumber;
@JsonProperty (PROPERTIES_FOCAL_LENGTH)
private Double focalLength;
@JsonProperty (PROPERTIES_ISO_SPEED_RATINGS)
private Integer isoSpeedRatings;
@JsonProperty (PROPERTIES_MANUFACTURER)
private String manufacturer;
@JsonProperty (PROPERTIES_MODEL)
private String model;
@JsonProperty (PROPERTIES_ORIENTATION)
private Integer orientation;
@JsonProperty (PROPERTIES_PIXEL_X_DIMENSION)
private Integer pixelXDimension;
@JsonProperty (PROPERTIES_PIXEL_Y_DIMENSION)
private Integer pixelYDimension;
@JsonProperty (PROPERTIES_RESOLUTION_UNIT)
private String resolutionUnit;
@JsonProperty (PROPERTIES_SOFTWARE)
private String software;
@JsonProperty (PROPERTIES_X_RESOLUTION)
private Double xResolution;
@JsonProperty (PROPERTIES_Y_RESOLUTION)
private Double yResolution;
@JsonProperty (PROPERTIES_RECORD_ORIGINATING_LOCATION)
private String originatingLocation;
@JsonProperty (PROPERTIES_RECORD_ORIGINATING_USER_ID)
private String originatingUserId;
@JsonProperty (PROPERTIES_RECORD_ORIGINATING_CREATION_DATE)
private String originatingCreationDate;
/*************************************/
/** Non-electronic record parameters */
/*************************************/
@JsonProperty (PROPERTIES_TITLE)
private String title;
@JsonProperty (PROPERTIES_SHELF)
private String shelf;
@JsonProperty (PROPERTIES_STORAGE_LOCATION)
private String storageLocation;
@JsonProperty (PROPERTIES_FILE)
private String file;
@JsonProperty (PROPERTIES_BOX)
private String box;
@JsonProperty (PROPERTIES_DESCRIPTION)
private String description;
@JsonProperty (PROPERTIES_NUMBER_OF_COPIES)
private Integer numberOfCopies;
@JsonProperty (PROPERTIES_PHYSICAL_SIZE)
private Integer physicalSize;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
}

View File

@@ -0,0 +1,101 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record category
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordCategory extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private RecordCategoryProperties properties;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private Boolean hasRetentionSchedule;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
}

View File

@@ -0,0 +1,112 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record category child
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordCategoryChild extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private Boolean isRecordCategory;
@JsonProperty
private Boolean isRecordFolder;
@JsonProperty
private RecordCategoryChildProperties properties;
@JsonProperty
private List<String> aspectNames;
@JsonProperty
private Boolean hasRetentionSchedule;
@JsonProperty
private Boolean isClosed;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
@JsonProperty
private String relativePath;
}

View File

@@ -0,0 +1,41 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import org.alfresco.rest.core.RestModels;
/**
* Handle collection of {@link RecordCategoryChildEntry}
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
public class RecordCategoryChildCollection extends RestModels<RecordCategoryChildEntry, RecordCategoryChildCollection>
{
}

View File

@@ -0,0 +1,48 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.core.RestModels;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* POJO for record category child entry
*
* @author Tuna Aksoy
* @since 2.6
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class RecordCategoryChildEntry extends RestModels<RecordCategory, RecordCategoryChildEntry>
{
@JsonProperty
private RecordCategoryChild entry;
}

View File

@@ -24,90 +24,83 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.recordcategory;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_BOX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FILE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_HOLD_REASON;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_HELD_CHILDREN_COUNT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IS_CLOSED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_NUMBER_OF_COPIES;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PHYSICAL_SIZE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_REVIEW_PERIOD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SHELF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SUPPLEMENTAL_MARKING_LIST;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_ID;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for file plan component properties
* POJO for record category child properties
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
//FIXME: Once the fields have been added the JsonIgnoreProperties annotation should be removed
@JsonIgnoreProperties (ignoreUnknown = true)
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponentProperties
public class RecordCategoryChildProperties extends TestModel
{
@JsonProperty(PROPERTIES_VITAL_RECORD_INDICATOR)
private Boolean vitalRecord;
@JsonProperty(PROPERTIES_TITLE)
/**************************************************************************/
/** Mandatory parameters - Shared by record categories and record folders */
/**************************************************************************/
@JsonProperty (required = true, value = PROPERTIES_TITLE)
private String title;
@JsonProperty(PROPERTIES_HOLD_REASON)
private String holdReason;
@JsonProperty (required = true, value = PROPERTIES_VITAL_RECORD_INDICATOR)
private Boolean vitalRecordIndicator;
@JsonProperty(PROPERTIES_DESCRIPTION)
@JsonProperty (required = true, value = PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_REVIEW_PERIOD)
@JsonSerialize (using = ReviewPeriodSerializer.class)
private ReviewPeriod reviewPeriod;
@JsonProperty (required = true, value = PROPERTIES_DESCRIPTION)
private String description;
@JsonProperty(PROPERTIES_SUPPLEMENTAL_MARKING_LIST)
private List<String> supplementalMarkingList;
/*********************************************************/
/** Optional parameters - Applies only to record folders */
/*********************************************************/
@JsonProperty (PROPERTIES_HELD_CHILDREN_COUNT)
private Integer heldChildrenCount;
@JsonProperty(PROPERTIES_REVIEW_PERIOD)
@JsonSerialize (using = ReviewPeriodSerializer.class)
private FilePlanComponentReviewPeriod reviewPeriod;
@JsonProperty(PROPERTIES_LOCATION)
@JsonProperty (PROPERTIES_LOCATION)
private String location;
@JsonProperty(value = PROPERTIES_IS_CLOSED, required = false)
@JsonProperty (PROPERTIES_IS_CLOSED)
private Boolean isClosed;
@JsonProperty(value = PROPERTIES_BOX, required = false)
private String box;
@JsonProperty(value = PROPERTIES_FILE, required = false)
private String file;
@JsonProperty(value = PROPERTIES_SHELF, required = false)
private String shelf;
@JsonProperty(value = PROPERTIES_NUMBER_OF_COPIES, required = false)
private Integer numberOfCopies;
@JsonProperty(value = PROPERTIES_PHYSICAL_SIZE, required = false)
private Integer physicalSize;
@JsonProperty(value = PROPERTIES_RECORD_ID, required = false)
private String rmIdentifier;
}
@JsonProperty (PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE)
private Boolean recordSearchHasDispositionSchedule;
}

View File

@@ -0,0 +1,41 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import org.alfresco.rest.core.RestModels;
/**
* Handle collection of {@link RecordCategoryEntry}
*
* @author Ramona Popa
* @author Tuna Aksoy
* @since 2.6
*/
public class RecordCategoryCollection extends RestModels<RecordCategoryEntry, RecordCategoryCollection>
{
}

View File

@@ -0,0 +1,50 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.core.RestModels;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* POJO for file plan entry
*
* @author Ramona Popa
* @author Tuna Aksoy
* @since 2.6
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class RecordCategoryEntry extends RestModels<FilePlan, RecordCategoryEntry>
{
@JsonProperty
private RecordCategory entry;
}

View File

@@ -0,0 +1,95 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordcategory;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_REVIEW_PERIOD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record category properties
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordCategoryProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_REVIEW_PERIOD)
@JsonSerialize (using = ReviewPeriodSerializer.class)
private ReviewPeriod reviewPeriod;
@JsonProperty (required = true, value = PROPERTIES_VITAL_RECORD_INDICATOR)
private Boolean vitalRecordIndicator;
/************************/
/** Optional parameters */
/************************/
@JsonProperty (PROPERTIES_TITLE)
private String title;
@JsonProperty (PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (PROPERTIES_DESCRIPTION)
private String description;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
}

View File

@@ -0,0 +1,100 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordfolder;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record folder
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordFolder extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private RecordFolderProperties properties;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private Boolean isClosed;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
}

View File

@@ -24,17 +24,18 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
package org.alfresco.rest.rm.community.model.recordfolder;
import org.alfresco.rest.core.RestModels;
/**
* Handle collection of FilePlanComponents
* Handle collection of {@link RecordFolderEntry}
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
public class FilePlanComponentsCollection extends RestModels<FilePlanComponentEntry, FilePlanComponentsCollection>
public class RecordFolderCollection extends RestModels<RecordFolderEntry, RecordFolderCollection>
{
}

View File

@@ -24,13 +24,12 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.ENTRY;
package org.alfresco.rest.rm.community.model.recordfolder;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.core.RestModels;
import org.alfresco.rest.rm.community.model.record.Record;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -39,7 +38,7 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for file plan component entry
* POJO for record folder entry
*
* @author Tuna Aksoy
* @since 2.6
@@ -49,8 +48,8 @@ import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponentEntry extends RestModels<FilePlanComponent, FilePlanComponentEntry>
public class RecordFolderEntry extends RestModels<RecordFolder, RecordFolderEntry>
{
@JsonProperty(ENTRY)
FilePlanComponent filePlanComponentModel;
@JsonProperty
private Record entry;
}

View File

@@ -0,0 +1,119 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.recordfolder;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_HELD_CHILDREN_COUNT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IS_CLOSED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD_EXPRESSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_REVIEW_PERIOD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record folder properties
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class RecordFolderProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IS_CLOSED)
private Boolean isClosed;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_HELD_CHILDREN_COUNT)
private Integer heldChildrenCount;
/************************/
/** Optional parameters */
/************************/
@JsonProperty (PROPERTIES_TITLE)
private String title;
@JsonProperty (PROPERTIES_VITAL_RECORD_INDICATOR)
private Boolean vitalRecordIndicator;
@JsonProperty (PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (PROPERTIES_LOCATION)
private String location;
@JsonProperty (PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE)
private Boolean recordSearchHasDispositionSchedule;
@JsonProperty (PROPERTIES_REVIEW_PERIOD)
@JsonSerialize (using = ReviewPeriodSerializer.class)
private ReviewPeriod reviewPeriod;
@JsonProperty (PROPERTIES_DESCRIPTION)
private String description;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
@JsonProperty (PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD)
private String recordSearchVitalRecordReviewPeriod;
@JsonProperty (PROPERTIES_RECORD_SEARCH_VITAL_RECORD_REVIEW_PERIOD_EXPRESSION)
private String recordSearchVitalRecordReviewPeriodExpression;
}

View File

@@ -26,8 +26,6 @@
*/
package org.alfresco.rest.rm.community.model.site;
import static org.alfresco.rest.rm.community.model.site.RMSiteFields.COMPLIANCE;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestSiteModel;
@@ -51,6 +49,6 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class RMSite extends RestSiteModel
{
@JsonProperty (value = COMPLIANCE, required = true)
@JsonProperty (required = true)
private RMSiteCompliance compliance;
}

View File

@@ -0,0 +1,89 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import java.util.List;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for Transfer
*
* @author Silviu Dinuta
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class Transfer extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private TransferProperties properties;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private List<String> allowableOperations;
}

View File

@@ -0,0 +1,110 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for transfer child
*
* @author Silviu Dinuta
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferChild extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private TransferChildProperties properties;
@JsonProperty
private Boolean isRecord;
@JsonProperty
private Boolean isRecordFolder;
@JsonProperty
private List<String> aspectNames;
@JsonProperty
private Boolean isCompleted;
@JsonProperty
private Boolean isClosed;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
}

View File

@@ -0,0 +1,40 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import org.alfresco.rest.core.RestModels;
/**
* Handle collection of {@link TransferChildEntry}
* @author Silviu Dinuta
* @since 2.6
*/
public class TransferChildCollection extends RestModels<TransferChildEntry, TransferChildCollection>
{
}

View File

@@ -0,0 +1,55 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import org.alfresco.rest.core.RestModels;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for transfer child entry
*
* @author Silviu Dinuta
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferChildEntry extends RestModels<Transfer, TransferChildEntry>
{
@JsonProperty
private TransferChild entry;
}

View File

@@ -0,0 +1,223 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_BOX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DATE_FILED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DATE_TIME_ORIGINAL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_EXPOSURE_TIME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FILE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FLASH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FOCAL_LENGTH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_F_NUMBER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_HELD_CHILDREN_COUNT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ISO_SPEED_RATINGS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IS_CLOSED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_MANUFACTURER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_MODEL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_NUMBER_OF_COPIES;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ORIENTATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ORIGINAL_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PHYSICAL_SIZE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PIXEL_X_DIMENSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PIXEL_Y_DIMENSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RESOLUTION_UNIT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_REVIEW_PERIOD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SHELF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SOFTWARE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_STORAGE_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VERSION_LABEL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VERSION_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_X_RESOLUTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_Y_RESOLUTION;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for transfer child properties
*
* @author Silviu Dinuta
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferChildProperties extends TestModel
{
/**************************************************************************/
/** Mandatory parameters - Shared by record folders and records*/
/**************************************************************************/
@JsonProperty (PROPERTIES_TITLE)
private String title;
@JsonProperty (required = true, value = PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (PROPERTIES_DESCRIPTION)
private String description;
/*********************************************************/
/** Optional parameters - Applies only to record folders */
/*********************************************************/
@JsonProperty (PROPERTIES_VITAL_RECORD_INDICATOR)
private Boolean vitalRecordIndicator;
@JsonProperty (PROPERTIES_REVIEW_PERIOD)
@JsonSerialize (using = ReviewPeriodSerializer.class)
private ReviewPeriod reviewPeriod;
@JsonProperty (PROPERTIES_HELD_CHILDREN_COUNT)
private Integer heldChildrenCount;
@JsonProperty (PROPERTIES_LOCATION)
private String location;
@JsonProperty (PROPERTIES_IS_CLOSED)
private Boolean isClosed;
/*********************************************************/
/** Optional parameters - Applies only to records */
/*********************************************************/
@JsonProperty (PROPERTIES_DATE_FILED)
private String dateField;
@JsonProperty (PROPERTIES_RECORD_SEARCH_HAS_DISPOSITION_SCHEDULE)
private Boolean recordSearchHasDispositionSchedule;
@JsonProperty (PROPERTIES_ORIGINAL_NAME)
private String originalName;
/*********************************/
/** Electronic record parameters */
/*********************************/
@JsonProperty (PROPERTIES_VERSION_TYPE)
private String versionType;
@JsonProperty (PROPERTIES_VERSION_LABEL)
private String versionLabel;
@JsonProperty (PROPERTIES_DATE_TIME_ORIGINAL)
private String dateTimeOriginal;
@JsonProperty (PROPERTIES_EXPOSURE_TIME)
private Double exposureTime;
@JsonProperty (PROPERTIES_FLASH)
private Boolean flash;
@JsonProperty (PROPERTIES_F_NUMBER)
private Double fNumber;
@JsonProperty (PROPERTIES_FOCAL_LENGTH)
private Double focalLength;
@JsonProperty (PROPERTIES_ISO_SPEED_RATINGS)
private Integer isoSpeedRatings;
@JsonProperty (PROPERTIES_MANUFACTURER)
private String manufacturer;
@JsonProperty (PROPERTIES_MODEL)
private String model;
@JsonProperty (PROPERTIES_ORIENTATION)
private Integer orientation;
@JsonProperty (PROPERTIES_PIXEL_X_DIMENSION)
private Integer pixelXDimension;
@JsonProperty (PROPERTIES_PIXEL_Y_DIMENSION)
private Integer pixelYDimension;
@JsonProperty (PROPERTIES_RESOLUTION_UNIT)
private String resolutionUnit;
@JsonProperty (PROPERTIES_SOFTWARE)
private String software;
@JsonProperty (PROPERTIES_X_RESOLUTION)
private Double xResolution;
@JsonProperty (PROPERTIES_Y_RESOLUTION)
private Double yResolution;
/*************************************/
/** Non-electronic record parameters */
/*************************************/
@JsonProperty (PROPERTIES_SHELF)
private String shelf;
@JsonProperty (PROPERTIES_STORAGE_LOCATION)
private String storageLocation;
@JsonProperty (PROPERTIES_FILE)
private String file;
@JsonProperty (PROPERTIES_BOX)
private String box;
@JsonProperty (PROPERTIES_NUMBER_OF_COPIES)
private Integer numberOfCopies;
@JsonProperty (PROPERTIES_PHYSICAL_SIZE)
private Integer physicalSize;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
}

View File

@@ -0,0 +1,40 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import org.alfresco.rest.core.RestModels;
/**
* Handle collection of {@link TransferEntry}
* @author Silviu Dinuta
* @since 2.6
*/
public class TransferCollection extends RestModels<TransferEntry, TransferCollection>
{
}

View File

@@ -0,0 +1,56 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import org.alfresco.rest.core.RestModels;
import org.alfresco.rest.rm.community.model.transfercontainer.TransferContainer;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for transfer entry
*
* @author Silviu Dinuta
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferEntry extends RestModels<TransferContainer, TransferEntry>
{
@JsonProperty
private Transfer entry;
}

View File

@@ -0,0 +1,88 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfer;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PDF_INDICATOR;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TRANSFER_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ACCESSION_INDICATOR;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for Transfer properties
*
* @author Dinuta Silviu
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
/************************/
/** Optional parameters */
/************************/
@JsonProperty (PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
@JsonProperty (PROPERTIES_PDF_INDICATOR)
private Boolean pdfIndicator;
@JsonProperty (PROPERTIES_TRANSFER_LOCATION)
private String transferLocation;
@JsonProperty (PROPERTIES_ACCESSION_INDICATOR)
private Boolean accessionIndicator;
}

View File

@@ -0,0 +1,95 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfercontainer;
import java.util.List;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for Transfer Container
*
* @author Silviu Dinuta
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferContainer extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private TransferContainerProperties properties;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private List<String> allowableOperations;
}

View File

@@ -0,0 +1,76 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.transfercontainer;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_COUNT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for Transfer Container properties
*
* @author Dinuta Silviu
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class TransferContainerProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
/************************/
/** Optional parameters */
/************************/
@JsonProperty (PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (PROPERTIES_COUNT)
private Integer count;
}

View File

@@ -0,0 +1,97 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.unfiledcontainer;
import java.util.List;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for unfiled container
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class UnfiledContainer extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private UnfiledContainerProperties properties;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
}

View File

@@ -24,21 +24,17 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.model.fileplancomponents;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.ALLOWABLE_OPERATIONS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.IS_CLOSED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.IS_COMPLETED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PATH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.RELATIVE_PATH;
package org.alfresco.rest.rm.community.model.unfiledcontainer;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -46,10 +42,9 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for file plan component
* POJO for record category child
*
* @author Tuna Aksoy
* @author Rodica Sutu
* @since 2.6
*/
@Builder
@@ -57,65 +52,68 @@ import lombok.NoArgsConstructor;
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class FilePlanComponent extends TestModel
public class UnfiledContainerChild extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private String id;
private String createdAt;
@JsonProperty (required = true)
private String parentId;
private Boolean isUnfiledRecordFolder;
@JsonProperty (required = true)
private String name;
private Boolean isRecord;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private Boolean isCategory;
@JsonProperty (required = true)
private Boolean isRecordFolder;
@JsonProperty (required = true)
private Boolean isFile;
@JsonProperty
private Boolean hasRetentionSchedule;
@JsonProperty(value = IS_CLOSED)
private Boolean isClosed;
@JsonProperty(value = IS_COMPLETED)
private Boolean isCompleted;
@JsonProperty (required = true)
private List<String> aspectNames;
@JsonProperty (required = true)
private FilePlanComponentUserInfo createdByUser;
@JsonProperty(value = PROPERTIES)
private FilePlanComponentProperties properties;
@JsonProperty (value = ALLOWABLE_OPERATIONS)
private List<String> allowableOperations;
@JsonProperty (required = false)
private FilePlanComponentContent content;
@JsonProperty (value = PATH)
private FilePlanComponentPath path;
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private String createdAt;
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private FilePlanComponentUserInfo modifiedByUser;
private String name;
@JsonProperty (value = RELATIVE_PATH)
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private UnfiledContainerChildProperties properties;
@JsonProperty
private List<String> aspectNames;
@JsonProperty
private Boolean hasRetentionSchedule;
@JsonProperty
private Boolean isClosed;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
@JsonProperty
private String relativePath;
@JsonProperty
private RecordContent content;
@JsonProperty
private Boolean isCompleted;
}

View File

@@ -0,0 +1,41 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.unfiledcontainer;
import org.alfresco.rest.core.RestModels;
/**
* Handle collection of {@link UnfiledContainerChildEntry}
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
public class UnfiledContainerChildCollection extends RestModels<UnfiledContainerChildEntry, UnfiledContainerChildCollection>
{
}

View File

@@ -0,0 +1,48 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.unfiledcontainer;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.alfresco.rest.core.RestModels;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* POJO for record category child entry
*
* @author Tuna Aksoy
* @since 2.6
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class UnfiledContainerChildEntry extends RestModels<UnfiledContainer, UnfiledContainerChildEntry>
{
@JsonProperty
private UnfiledContainerChild entry;
}

View File

@@ -0,0 +1,196 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.unfiledcontainer;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_BOX;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DATE_TIME_ORIGINAL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_DESCRIPTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_EXPOSURE_TIME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FILE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FLASH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_FOCAL_LENGTH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_F_NUMBER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ISO_SPEED_RATINGS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_MANUFACTURER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_MODEL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_NUMBER_OF_COPIES;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ORIENTATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ORIGINAL_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PHYSICAL_SIZE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PIXEL_X_DIMENSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_PIXEL_Y_DIMENSION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_RESOLUTION_UNIT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_REVIEW_PERIOD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SHELF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_SOFTWARE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_STORAGE_LOCATION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VERSION_LABEL;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VERSION_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_VITAL_RECORD_INDICATOR;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_X_RESOLUTION;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_Y_RESOLUTION;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.util.ReviewPeriodSerializer;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for record category child properties
*
* @author Tuna Aksoy
* @author Ana Bozianu
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class UnfiledContainerChildProperties extends TestModel
{
/**************************************************************************/
/** Mandatory parameters - Shared by unfiled record folder and records */
/**************************************************************************/
@JsonProperty (required = true, value = PROPERTIES_TITLE)
private String title;
@JsonProperty (required = true, value = PROPERTIES_VITAL_RECORD_INDICATOR)
private Boolean vitalRecordIndicator;
@JsonProperty (required = true, value = PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_REVIEW_PERIOD)
@JsonSerialize (using = ReviewPeriodSerializer.class)
private ReviewPeriod reviewPeriod;
@JsonProperty (required = true, value = PROPERTIES_DESCRIPTION)
private String description;
/*********************************/
/** Electronic record parameters */
/*********************************/
@JsonProperty (PROPERTIES_VERSION_TYPE)
private String versionType;
@JsonProperty (PROPERTIES_VERSION_LABEL)
private String versionLabel;
@JsonProperty (PROPERTIES_DATE_TIME_ORIGINAL)
private String dateTimeOriginal;
@JsonProperty (PROPERTIES_EXPOSURE_TIME)
private Double exposureTime;
@JsonProperty (PROPERTIES_FLASH)
private Boolean flash;
@JsonProperty (PROPERTIES_F_NUMBER)
private Double fNumber;
@JsonProperty (PROPERTIES_FOCAL_LENGTH)
private Double focalLength;
@JsonProperty (PROPERTIES_ISO_SPEED_RATINGS)
private Integer isoSpeedRatings;
@JsonProperty (PROPERTIES_MANUFACTURER)
private String manufacturer;
@JsonProperty (PROPERTIES_MODEL)
private String model;
@JsonProperty (PROPERTIES_ORIENTATION)
private Integer orientation;
@JsonProperty (PROPERTIES_PIXEL_X_DIMENSION)
private Integer pixelXDimension;
@JsonProperty (PROPERTIES_PIXEL_Y_DIMENSION)
private Integer pixelYDimension;
@JsonProperty (PROPERTIES_RESOLUTION_UNIT)
private String resolutionUnit;
@JsonProperty (PROPERTIES_SOFTWARE)
private String software;
@JsonProperty (PROPERTIES_X_RESOLUTION)
private Double xResolution;
@JsonProperty (PROPERTIES_Y_RESOLUTION)
private Double yResolution;
@JsonProperty (PROPERTIES_ORIGINAL_NAME)
private String originalName;
/*************************************/
/** Non-electronic record parameters */
/*************************************/
@JsonProperty (PROPERTIES_SHELF)
private String shelf;
@JsonProperty (PROPERTIES_STORAGE_LOCATION)
private String storageLocation;
@JsonProperty (PROPERTIES_FILE)
private String file;
@JsonProperty (PROPERTIES_BOX)
private String box;
@JsonProperty (PROPERTIES_NUMBER_OF_COPIES)
private Integer numberOfCopies;
@JsonProperty (PROPERTIES_PHYSICAL_SIZE)
private Integer physicalSize;
@JsonProperty (PROPERTIES_OWNER)
private Owner owner;
}

View File

@@ -0,0 +1,71 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.unfiledcontainer;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_IDENTIFIER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ID_IS_TEMPORARILY_EDITABLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_OWNER;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_ROOT_NODE_REF;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PROPERTIES_TITLE;
import org.alfresco.rest.rm.community.model.common.Owner;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for file plan properties
*
* @author Tuna Aksoy
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class UnfiledContainerProperties extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true, value = PROPERTIES_ID_IS_TEMPORARILY_EDITABLE)
private Boolean idIsTemporarilyEditable;
@JsonProperty (required = true, value = PROPERTIES_IDENTIFIER)
private String identifier;
@JsonProperty (required = true, value = PROPERTIES_ROOT_NODE_REF)
private String rootNodeRef;
}

View File

@@ -0,0 +1,113 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.model.unfiledcontainer;
import java.util.List;
import org.alfresco.rest.model.RestByUserModel;
import org.alfresco.rest.rm.community.model.common.Path;
import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.utility.model.TestModel;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* POJO for unfiled container
*
* @author Ramona Popa
* @since 2.6
*/
@Builder
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
public class UnfiledRecordFolder extends TestModel
{
/*************************/
/** Mandatory parameters */
/*************************/
@JsonProperty (required = true)
private String createdAt;
@JsonProperty (required = true)
private RestByUserModel createdByUser;
@JsonProperty (required = true)
private String modifiedAt;
@JsonProperty (required = true)
private RestByUserModel modifiedByUser;
@JsonProperty (required = true)
private String name;
@JsonProperty (required = true)
private String id;
@JsonProperty (required = true)
private String nodeType;
@JsonProperty (required = true)
private String parentId;
/************************/
/** Optional parameters */
/************************/
@JsonProperty
private UnfiledContainerChildProperties properties;
@JsonProperty
private List<String> aspectNames;
@JsonProperty
private Boolean hasRetentionSchedule;
@JsonProperty
private Boolean isClosed;
@JsonProperty
private List<String> allowableOperations;
@JsonProperty
private Path path;
@JsonProperty
private String relativePath;
@JsonProperty
private RecordContent content;
@JsonProperty
private Boolean isCompleted;
}

View File

@@ -26,9 +26,15 @@
*/
package org.alfresco.rest.rm.community.requests;
import static lombok.AccessLevel.PRIVATE;
import static lombok.AccessLevel.PROTECTED;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.requests.ModelRequest;
import lombok.Getter;
import lombok.Setter;
/**
* Extends {@link ModelRequest} to set {@link RMRestWrapper}
*
@@ -37,22 +43,16 @@ import org.alfresco.rest.requests.ModelRequest;
*/
public abstract class RMModelRequest extends ModelRequest<RMModelRequest>
{
@Getter (value = PROTECTED)
@Setter (value = PRIVATE)
private RMRestWrapper rmRestWrapper;
/**
* @return the rmRestWrapper
*/
public RMRestWrapper getRMRestWrapper()
{
return this.rmRestWrapper;
}
/**
* @param rmRestWrapper
* @param restWrapper
*/
public RMModelRequest(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper.getRestWrapper());
this.rmRestWrapper = rmRestWrapper;
setRmRestWrapper(rmRestWrapper);
}
}

View File

@@ -0,0 +1,182 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore;
import static java.lang.Integer.parseInt;
import static java.lang.String.format;
import com.jayway.restassured.RestAssured;
import org.alfresco.rest.core.RMRestProperties;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.FilesAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMUserAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
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.TransferAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.TransferContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledRecordFolderAPI;
/**
* Defines the entire GS Core API
* {@link http://host:port/gs-api-explorer} select "GS Core API"
*
* @author Tuna Aksoy
* @since 2.6
*/
public class GSCoreAPI extends RMModelRequest
{
/**
* Constructor
*
* @param rmRestWrapper RM REST Wrapper
* @param rmRestProperties RM REST Properties
*/
public GSCoreAPI(RMRestWrapper rmRestWrapper, RMRestProperties rmRestProperties)
{
super(rmRestWrapper);
RestAssured.baseURI = format("%s://%s", rmRestProperties.getScheme(), rmRestProperties.getServer());
RestAssured.port = parseInt(rmRestProperties.getPort());
RestAssured.basePath = rmRestProperties.getRestRmPath();
restWrapper.configureRequestSpec().setBasePath(RestAssured.basePath);
}
/**
* Provides DSL on all REST calls under <code>ig-sites/rm/...</code> API path
*
* @return {@link RMSiteAPI}
*/
public RMSiteAPI usingRMSite()
{
return new RMSiteAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>file-plans/...</code> API path
*
* @return {@link FilePlanAPI}
*/
public FilePlanAPI usingFilePlans()
{
return new FilePlanAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>record-categories/...</code> API path
*
* @return {@link RecordCategoryAPI}
*/
public RecordCategoryAPI usingRecordCategory()
{
return new RecordCategoryAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>record-folders/...</code> API path
*
* @return {@link RecordFolderAPI}
*/
public RecordFolderAPI usingRecordFolder()
{
return new RecordFolderAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>records/...</code> API path
*
* @return {@link FilePlanComponentAPI}
*/
public RecordsAPI usingRecords()
{
return new RecordsAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>files/...</code> API path
*
* @return {@link FilesAPI}
*/
public FilesAPI usingFiles()
{
return new FilesAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>transfer-containers/...</code> API path
*
* @return {@link TransferContainerAPI}
*/
public TransferContainerAPI usingTransferContainer()
{
return new TransferContainerAPI(getRmRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>transfers/...</code> API path
*
* @return {@link TransferAPI}
*/
public TransferAPI usingTransfer()
{
return new TransferAPI(getRmRestWrapper());
}
/**
* Provides DSL for RM unfiled container API
*
* @return {@link UnfiledContainerAPI}
*/
public UnfiledContainerAPI usingUnfiledContainers()
{
return new UnfiledContainerAPI(getRmRestWrapper());
}
/**
* Provides DSL for RM unfiled record folders API
*
* @return {@link UnfiledRecordFolderAPI}
*/
public UnfiledRecordFolderAPI usingUnfiledRecordFolder()
{
return new UnfiledRecordFolderAPI(getRmRestWrapper());
}
/**
* Provides DSL for RM user management API
*
* @return {@link RMUserAPI}
*/
public RMUserAPI usingRMUser()
{
return new RMUserAPI(getRmRestWrapper());
}
}

View File

@@ -0,0 +1,175 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* File plan REST API Wrapper
*
* @author Ramona Popa
* @author Tuna Aksoy
* @since 2.6
*/
public class FilePlanAPI extends RMModelRequest
{
/**
* Constructor.
*
* @param restWrapper
*/
public FilePlanAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* see {@link #getFilePlan(String, String)}
*/
public FilePlan getFilePlan(String filePlanId)
{
mandatoryString("filePlanId", filePlanId);
return getFilePlan(filePlanId, EMPTY);
}
/**
* Gets a file plan.
*
* @param filePlanId The identifier of a file plan
* @param parameters The URL parameters to add
* @return The {@link FilePlan} for the given {@code filePlanId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code filePlanId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code filePlanId}</li>
* <li>{@code filePlanId} does not exist</li>
* </ul>
*/
public FilePlan getFilePlan(String filePlanId, String parameters)
{
mandatoryString("filePlanId", filePlanId);
return getRmRestWrapper().processModel(FilePlan.class, simpleRequest(
GET,
"/file-plans/{filePlanId}?{parameters}",
filePlanId,
parameters
));
}
/**
* see {@link #getRootRecordCategories(String, String)}
*/
public RecordCategoryCollection getRootRecordCategories(String filePlanId)
{
mandatoryString("filePlanId", filePlanId);
return getRootRecordCategories(filePlanId, EMPTY);
}
/**
* Gets the children (root categories) of a file plan.
*
* @param filePlanId The identifier of a file plan
* @param parameters The URL parameters to add
* @return The {@link RecordCategoryCollection} for the given {@code filePlanId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code filePlanId}</li>
* <li>{@code filePlanId} does not exist</li>
*</ul>
*/
public RecordCategoryCollection getRootRecordCategories(String filePlanId, String parameters)
{
mandatoryString("filePlanId", filePlanId);
return getRmRestWrapper().processModels(RecordCategoryCollection.class, simpleRequest(
GET,
"file-plans/{filePlanId}/categories?{parameters}",
filePlanId,
parameters
));
}
/**
* see {@link #createRootRecordCategory(RecordCategory, String, String)}
*/
public RecordCategory createRootRecordCategory(RecordCategory recordCategoryModel, String filePlanId) throws Exception
{
mandatoryObject("recordCategoryModel", recordCategoryModel);
mandatoryString("filePlanId", filePlanId);
return createRootRecordCategory(recordCategoryModel, filePlanId, EMPTY);
}
/**
* Creates a root record category.
*
* @param recordCategoryModel The record category model which holds the information
* @param filePlanId The identifier of a file plan
* @param parameters The URL parameters to add
* @return The created {@link RecordCategory}
* @throws Exception for the following cases:
* <ul>
* <li>{@code filePlanId} is not a valid format or {@code filePlanId} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code filePlanId}</li>
* <li>{@code filePlanIds} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public RecordCategory createRootRecordCategory(RecordCategory recordCategoryModel, String filePlanId, String parameters) throws Exception
{
mandatoryObject("recordCategoryModel", recordCategoryModel);
mandatoryString("filePlanId", filePlanId);
return getRmRestWrapper().processModel(RecordCategory.class, requestWithBody(
POST,
toJson(recordCategoryModel),
"file-plans/{filePlanId}/categories?{parameters}",
filePlanId,
parameters
));
}
}

View File

@@ -24,7 +24,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.requests.igCoreAPI;
package org.alfresco.rest.rm.community.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
@@ -32,10 +32,8 @@ import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.POST;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* Files REST API Wrapper
@@ -43,8 +41,6 @@ import org.springframework.stereotype.Component;
* @author Kristijan Conkas
* @since 2.6
*/
@Component
@Scope (value = "prototype")
public class FilesAPI extends RMModelRequest
{
/**
@@ -57,16 +53,17 @@ public class FilesAPI extends RMModelRequest
/**
* Declare file as record
*
* @param fileId The Id of a file to declare as record
* @param parameters Request parameters, refer to API documentation for more details
* @return The {@link FilePlanComponent} for created record
* @return The {@link Record} for created record
* @throws Exception for malformed JSON responses
*/
public FilePlanComponent declareAsRecord(String fileId, String parameters) throws Exception
public Record declareAsRecord(String fileId, String parameters) throws Exception
{
mandatoryString("fileId", fileId);
return getRMRestWrapper().processModel(FilePlanComponent.class, simpleRequest(
return getRmRestWrapper().processModel(Record.class, simpleRequest(
POST,
"/files/{fileId}/declare?{parameters}",
fileId,
@@ -76,12 +73,15 @@ public class FilesAPI extends RMModelRequest
/**
* A no-parameter version of {@link FilesAPI#declareAsRecord}
*
* @param fileId The Id of a file to declare as record
* @return The {@link FilePlanComponent} for created record
* @return The {@link Record} for created record
* @throws Exception for malformed JSON responses
*/
public FilePlanComponent declareAsRecord(String fileId) throws Exception
public Record declareAsRecord(String fileId) throws Exception
{
mandatoryString("fileId", fileId);
return declareAsRecord(fileId, EMPTY);
}
}

View File

@@ -24,7 +24,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.requests.igCoreAPI;
package org.alfresco.rest.rm.community.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
@@ -72,9 +72,9 @@ public class RMSiteAPI extends RMModelRequest
*/
public RMSite getSite() throws Exception
{
return getRMRestWrapper().processModel(RMSite.class, simpleRequest(
return getRmRestWrapper().processModel(RMSite.class, simpleRequest(
GET,
"ig-sites/rm"
"gs-sites/rm"
));
}
@@ -95,10 +95,10 @@ public class RMSiteAPI extends RMModelRequest
{
mandatoryObject("rmSiteModel", rmSiteModel);
return getRMRestWrapper().processModel(RMSite.class, requestWithBody(
return getRmRestWrapper().processModel(RMSite.class, requestWithBody(
POST,
toJson(rmSiteModel),
"ig-sites"
"gs-sites"
));
}
@@ -115,9 +115,9 @@ public class RMSiteAPI extends RMModelRequest
*/
public void deleteRMSite() throws Exception
{
getRMRestWrapper().processEmptyModel(simpleRequest(
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"ig-sites/rm"
"gs-sites/rm"
));
}
@@ -139,10 +139,10 @@ public class RMSiteAPI extends RMModelRequest
{
mandatoryObject("rmSiteProperties", rmSiteModel);
return getRMRestWrapper().processModel(RMSite.class, requestWithBody(
return getRmRestWrapper().processModel(RMSite.class, requestWithBody(
PUT,
toJson(rmSiteModel),
"ig-sites/rm"
"gs-sites/rm"
));
}
@@ -161,6 +161,6 @@ public class RMSiteAPI extends RMModelRequest
public boolean existsRMSite() throws Exception
{
getSite();
return getRMRestWrapper().getStatusCode().equals(OK.toString());
return getRmRestWrapper().getStatusCode().equals(OK.toString());
}
}

View File

@@ -24,7 +24,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.requests.igCoreAPI;
package org.alfresco.rest.rm.community.requests.gscore.api;
import static com.jayway.restassured.RestAssured.basic;
import static com.jayway.restassured.RestAssured.given;
@@ -42,13 +42,10 @@ import org.alfresco.dataprep.AlfrescoHttpClient;
import org.alfresco.dataprep.AlfrescoHttpClientFactory;
import org.alfresco.rest.core.RMRestProperties;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.alfresco.utility.model.UserModel;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* RM user management API
@@ -59,8 +56,6 @@ import org.springframework.stereotype.Component;
// FIXME: As of December 2016 there is no v1-style API for managing RM users and users'
// roles/permissions. Until such APIs have become available, methods in this class are just proxies to
// "old-style" API calls.
@Component
@Scope (value = "prototype")
public class RMUserAPI extends RMModelRequest
{
/**
@@ -77,16 +72,16 @@ public class RMUserAPI extends RMModelRequest
*/
private AlfrescoHttpClient getAlfrescoHttpClient()
{
RMRestProperties properties = getRMRestWrapper().getRmRestProperties();
RMRestProperties properties = getRmRestWrapper().getRmRestProperties();
AlfrescoHttpClientFactory factory = new AlfrescoHttpClientFactory();
factory.setHost(properties.getServer());
factory.setPort(Integer.parseInt(properties.getPort()));
factory.setScheme(properties.getScheme());
return factory.getObject();
}
/**
* Assign RM role to user
* @param userName User's username
@@ -95,8 +90,8 @@ public class RMUserAPI extends RMModelRequest
*/
public void assignRoleToUser(String userName, String userRole) throws Exception
{
UserModel adminUser = getRMRestWrapper().getTestUser();
UserModel adminUser = getRmRestWrapper().getTestUser();
// get an "old-style" REST API client
AlfrescoHttpClient client = getAlfrescoHttpClient();
@@ -111,25 +106,25 @@ public class RMUserAPI extends RMModelRequest
.log().all()
.pathParam("role", userRole)
.pathParam("authority", userName)
.param("alf_ticket", client.getAlfTicket(adminUser.getUsername(),
.param("alf_ticket", client.getAlfTicket(adminUser.getUsername(),
adminUser.getPassword()))
.when()
.post("/rm/roles/{role}/authorities/{authority}")
.prettyPeek()
.andReturn();
getRMRestWrapper().setStatusCode(Integer.toString(response.getStatusCode()));
getRmRestWrapper().setStatusCode(Integer.toString(response.getStatusCode()));
}
/**
* Helper method to add permission on a component to user
* @param component {@link FilePlanComponent} on which permission should be given
* @param component The id of the file plan component on which permission should be given
* @param user {@link UserModel} for a user to be granted permission
* @param permission {@link UserPermissions} to be granted
*/
public void addUserPermission(FilePlanComponent component, UserModel user, String permission)
public void addUserPermission(String filePlanComponentId, UserModel user, String permission)
{
UserModel adminUser = getRMRestWrapper().getTestUser();
UserModel adminUser = getRmRestWrapper().getTestUser();
// get an "old-style" REST API client
AlfrescoHttpClient client = getAlfrescoHttpClient();
@@ -146,20 +141,20 @@ public class RMUserAPI extends RMModelRequest
.setBaseUri(client.getApiUrl())
.setBasePath("/")
.build();
// execute an "old-style" API call
Response response = given()
.spec(spec)
.auth().basic(adminUser.getUsername(), adminUser.getPassword())
.contentType(ContentType.JSON)
.body(bodyJson.toString())
.pathParam("nodeId", component.getId())
.pathParam("nodeId", filePlanComponentId)
.log().all()
.when()
.post("/node/workspace/SpacesStore/{nodeId}/rmpermissions")
.prettyPeek()
.andReturn();
getRMRestWrapper().setStatusCode(Integer.toString(response.getStatusCode()));
getRmRestWrapper().setStatusCode(Integer.toString(response.getStatusCode()));
}
/**
@@ -172,9 +167,9 @@ public class RMUserAPI extends RMModelRequest
*/
public boolean createUser(String userName, String userPassword, String userEmail)
{
UserModel adminUser = getRMRestWrapper().getTestUser();
UserModel adminUser = getRmRestWrapper().getTestUser();
AlfrescoHttpClient client = getAlfrescoHttpClient();
JsonObject body = buildObject()
.add("userName", userName)
.add("firstName", userName)
@@ -182,7 +177,7 @@ public class RMUserAPI extends RMModelRequest
.add("password", userPassword)
.add("email", userEmail)
.getJson();
RequestSpecification spec = new RequestSpecBuilder()
.setBaseUri(client.getApiUrl())
.setBasePath("/")
@@ -190,7 +185,7 @@ public class RMUserAPI extends RMModelRequest
.setContentType(ContentType.JSON)
.setBody(body.toString())
.build();
// create POST request to "people" endpoint
Response response = given()
.spec(spec)
@@ -199,7 +194,7 @@ public class RMUserAPI extends RMModelRequest
.post("people")
.prettyPeek()
.andReturn();
return (response.getStatusCode() == OK.value());
}
}

View File

@@ -0,0 +1,242 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.DELETE;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* Record category REST API Wrapper
*
* @author Tuna Aksoy
* @since 2.6
*/
public class RecordCategoryAPI extends RMModelRequest
{
/**
* Constructor.
*
* @param restWrapper
*/
public RecordCategoryAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* Deletes a record category.
*
* @param recordCategoryId The identifier of a record category
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordCategoryId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
* <li>{@code recordCategoryId} is locked and cannot be deleted</li>
* </ul>
*/
public void deleteRecordCategory(String recordCategoryId)
{
mandatoryString("recordCategoryId", recordCategoryId);
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"record-categories/{recordCategoryId}",
recordCategoryId
));
}
/**
* see {@link #getRecordCategory(String, String)}
*/
public RecordCategory getRecordCategory(String recordCategoryId)
{
mandatoryString("recordCategoryId", recordCategoryId);
return getRecordCategory(recordCategoryId, EMPTY);
}
/**
* Gets a record category.
*
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @return The {@link RecordCategory} for the given {@code recordCategoryId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordCategoryId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
* </ul>
*/
public RecordCategory getRecordCategory(String recordCategoryId, String parameters)
{
mandatoryString("recordCategoryId", recordCategoryId);
return getRmRestWrapper().processModel(RecordCategory.class, simpleRequest(
GET,
"record-categories/{recordCategoryId}?{parameters}",
recordCategoryId,
parameters
));
}
/**
* see {@link #updateRecordCategory(RecordCategory, String, String)
*/
public RecordCategory updateRecordCategory(RecordCategory recordCategoryModel, String recordCategoryId) throws Exception
{
mandatoryObject("recordCategoryModel", recordCategoryModel);
mandatoryString("recordCategoryId", recordCategoryId);
return updateRecordCategory(recordCategoryModel, recordCategoryId, EMPTY);
}
/**
* Updates a record category.
*
* @param recordCategoryModel The record category model which holds the information
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @param returns The updated {@link RecordCategory}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code recordCategoryId} is not a valid format or {@code recordCategoryModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
* <li>the updated name clashes with an existing record category in the current parent category</li>
* <li>model integrity exception, including file name with invalid characters</li>
* </ul>
*/
public RecordCategory updateRecordCategory(RecordCategory recordCategoryModel, String recordCategoryId, String parameters) throws Exception
{
mandatoryObject("recordCategoryModel", recordCategoryModel);
mandatoryString("recordCategoryId", recordCategoryId);
return getRmRestWrapper().processModel(RecordCategory.class, requestWithBody(
PUT,
toJson(recordCategoryModel),
"record-categories/{recordCategoryId}?{parameters}",
recordCategoryId,
parameters
));
}
/**
* see {@link #getRecordCategoryChildren(String, String)}
*/
public RecordCategoryChildCollection getRecordCategoryChildren(String recordCategoryId)
{
mandatoryString("recordCategoryId", recordCategoryId);
return getRecordCategoryChildren(recordCategoryId, EMPTY);
}
/**
* Gets the children of a record category.
*
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @return The {@link RecordCategoryChildCollection} for the given {@code recordCategoryId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
*</ul>
*/
public RecordCategoryChildCollection getRecordCategoryChildren(String recordCategoryId, String parameters)
{
mandatoryString("recordCategoryId", recordCategoryId);
return getRmRestWrapper().processModels(RecordCategoryChildCollection.class, simpleRequest(
GET,
"record-categories/{recordCategoryId}/children?{parameters}",
recordCategoryId,
parameters
));
}
/**
* see {@link #createRecordCategoryChild(RecordCategoryChild, String, String)}
*/
public RecordCategoryChild createRecordCategoryChild(RecordCategoryChild recordCategoryChildModel, String recordCategoryId) throws Exception
{
mandatoryObject("recordCategoryChildModel", recordCategoryChildModel);
mandatoryString("recordCategoryId", recordCategoryId);
return createRecordCategoryChild(recordCategoryChildModel, recordCategoryId, EMPTY);
}
/**
* Creates a record category child. Can be a record category or a record folder.
*
* @param recordCategoryChildModel The record category child model which holds the information
* @param recordCategoryId The identifier of a record category
* @param parameters The URL parameters to add
* @return The created {@link RecordCategoryChild}
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordCategoryId} is not a valid format or {@code recordCategoryChildModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code recordCategoryId}</li>
* <li>{@code recordCategoryId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public RecordCategoryChild createRecordCategoryChild(RecordCategoryChild recordCategoryChildModel, String recordCategoryId, String parameters) throws Exception
{
mandatoryObject("filePlanComponentProperties", recordCategoryChildModel);
mandatoryString("recordCategoryId", recordCategoryId);
return getRmRestWrapper().processModel(RecordCategoryChild.class, requestWithBody(
POST,
toJson(recordCategoryChildModel),
"record-categories/{recordCategoryId}/children?{parameters}",
recordCategoryId,
parameters
));
}
}

View File

@@ -0,0 +1,291 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.DELETE;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
import static org.testng.Assert.fail;
import java.io.File;
import java.util.Iterator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.http.ContentType;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.alfresco.rest.rm.community.util.FilePlanComponentMixIn;
/**
* Record folder REST API Wrapper
*
* @author Tuna Aksoy
* @since 2.6
*/
public class RecordFolderAPI extends RMModelRequest
{
/**
* Constructor.
*
* @param restWrapper
*/
public RecordFolderAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* Deletes a record folder.
*
* @param recordFolderId The identifier of a record folder
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordFolderId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code recordFolderId}</li>
* <li>{@code recordFolderId} does not exist</li>
* <li>{@code recordFolderId} is locked and cannot be deleted</li>
* </ul>
*/
public void deleteRecordFolder(String recordFolderId)
{
mandatoryString("recordFolderId", recordFolderId);
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"record-folders/{recordFolderId}",
recordFolderId
));
}
/**
* see {@link #getRecordFolder(String, String)}
*/
public RecordFolder getRecordFolder(String recordFolderId)
{
mandatoryString("recordFolderId", recordFolderId);
return getRecordFolder(recordFolderId, EMPTY);
}
/**
* Gets a record folder.
*
* @param recordFolderId The identifier of a record folder
* @param parameters The URL parameters to add
* @return The {@link RecordFolder} for the given {@code recordFolderId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordFolderId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordFolderId}</li>
* <li>{@code recordFolderId} does not exist</li>
* </ul>
*/
public RecordFolder getRecordFolder(String recordFolderId, String parameters)
{
mandatoryString("recordFolderId", recordFolderId);
return getRmRestWrapper().processModel(RecordFolder.class, simpleRequest(
GET,
"record-folders/{recordFolderId}?{parameters}",
recordFolderId,
parameters
));
}
/**
* see {@link #updateRecordFolder(RecordFolder, String, String)
*/
public RecordFolder updateRecordFolder(RecordFolder recordFolderModel, String recordFolderId) throws Exception
{
mandatoryObject("recordFolderModel", recordFolderModel);
mandatoryString("recordFolderId", recordFolderId);
return updateRecordFolder(recordFolderModel, recordFolderId, EMPTY);
}
/**
* Updates a record folder.
*
* @param recordFolderModel The record folder model which holds the information
* @param recordFolderId The identifier of a record folder
* @param parameters The URL parameters to add
* @param returns The updated {@link RecordFolder}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code recordFolderId} is not a valid format or {@code recordFolderModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code recordFolderId}</li>
* <li>{@code recordFolderId} does not exist</li>
* <li>the updated name clashes with an existing record folder in the current parent category</li>
* <li>model integrity exception, including file name with invalid characters</li>
* </ul>
*/
public RecordFolder updateRecordFolder(RecordFolder recordFolderModel, String recordFolderId, String parameters) throws Exception
{
mandatoryObject("recordFolderModel", recordFolderModel);
mandatoryString("recordFolderId", recordFolderId);
return getRmRestWrapper().processModel(RecordFolder.class, requestWithBody(
PUT,
toJson(recordFolderModel),
"record-folders/{recordFolderId}?{parameters}",
recordFolderId,
parameters
));
}
/**
* see {@link #getRecordFolderChildren(String, String)}
*/
public RecordFolderCollection getRecordFolderChildren(String recordFolderId)
{
mandatoryString("recordFolderId", recordFolderId);
return getRecordFolderChildren(recordFolderId, EMPTY);
}
/**
* Gets the children of a record folder.
*
* @param recordFolderId The identifier of a record folder
* @param parameters The URL parameters to add
* @return The {@link RecordFolderCollection} for the given {@code recordFolderId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordFolderId}</li>
* <li>{@code recordFolderId} does not exist</li>
*</ul>
*/
public RecordFolderCollection getRecordFolderChildren(String recordFolderId, String parameters)
{
mandatoryString("recordFolderId", recordFolderId);
return getRmRestWrapper().processModels(RecordFolderCollection.class, simpleRequest(
GET,
"record-folders/{recordFolderId}/records?{parameters}",
recordFolderId,
parameters
));
}
/**
* see {@link #createRecord(Record, String, String)}
*/
public Record createRecord(Record recordModel, String recordFolderId) throws Exception
{
mandatoryObject("recordModel", recordModel);
mandatoryString("recordFolderId", recordFolderId);
return createRecord(recordModel, recordFolderId, EMPTY);
}
/**
* Create a record from file resource
*
* @param electronicRecordModel {@link Record} for electronic record to be created
* @param recordContent {@link File} pointing to the content of the electronic record to be created
* @param recordFolderId The identifier of a record folder
* @return newly created {@link Record}
* @throws Exception for invalid recordModel JSON strings
*/
public Record createRecord(Record recordModel, String recordFolderId, File recordContent) throws Exception
{
mandatoryString("recordFolderId", recordFolderId);
mandatoryObject("recordContent", recordContent);
mandatoryObject("recordModel", recordModel);
if (!recordModel.getNodeType().equals(CONTENT_TYPE))
{
fail("Only electronic records are supported");
}
/*
* For file uploads nodeBodyCreate is ignored hence can't be used. Append all Record fields
* to the request.
*/
RequestSpecBuilder builder = getRmRestWrapper().configureRequestSpec();
JsonNode root = new ObjectMapper().readTree(toJson(recordModel, Record.class, FilePlanComponentMixIn.class));
// add request fields
Iterator<String> fieldNames = root.fieldNames();
while (fieldNames.hasNext())
{
String fieldName = fieldNames.next();
builder.addMultiPart(fieldName, root.get(fieldName).asText(), ContentType.JSON.name());
}
builder.addMultiPart("filedata", recordContent, ContentType.BINARY.name());
// create node with given content
return createRecord(recordModel, recordFolderId);
}
/**
* Creates a record in a record folder child, i.e. a record.
*
* @param recordModel The record model which holds the information
* @param recordfolderId The identifier of a record folder
* @param parameters The URL parameters to add
* @return The created {@link Record}
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordFolderId is not a valid format or {@code recordModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code recordFolderId}</li>
* <li>{@code recordFolderId} does not exist</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public Record createRecord(Record recordModel, String recordFolderId, String parameters) throws Exception
{
mandatoryObject("recordModel", recordModel);
mandatoryString("recordFolderId", recordFolderId);
return getRmRestWrapper().processModel(Record.class, requestWithBody(
POST,
toJson(recordModel),
"record-folders/{recordFolderId}/records?{parameters}",
recordFolderId,
parameters
));
}
}

View File

@@ -24,35 +24,32 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
package org.alfresco.rest.rm.community.requests.igCoreAPI;
package org.alfresco.rest.rm.community.requests.gscore.api;
import static com.jayway.restassured.RestAssured.given;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.DELETE;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
import com.jayway.restassured.response.ResponseBody;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.RecordBodyFile;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordBodyFile;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* Records REST API Wrapper
* Records REST API Wrapper
*
* @author Rodica Sutu
* @since 2.6
*/
@Component
@Scope (value = "prototype")
public class RecordsAPI extends RMModelRequest
{
/**
@@ -79,11 +76,11 @@ public class RecordsAPI extends RMModelRequest
public ResponseBody<?> getRecordContent(String recordId) throws Exception
{
mandatoryString("recordId", recordId);
return getRMRestWrapper()
return getRmRestWrapper()
.processHtmlResponse(simpleRequest(GET,"records/{recordId}/content", recordId))
.getBody();
}
/**
@@ -91,7 +88,7 @@ public class RecordsAPI extends RMModelRequest
*
* @param recordBodyFile The properties where to file the record
* @param recordId The id of the record to file
* @return The {@link FilePlanComponent} with the given properties
* @return The {@link Record} with the given properties
* @throws Exception for the following cases:
* <ul>
* <li>Invalid parameter: {@code recordBodyFile} is not a valid format,{@code recordId} is not a record</li>
@@ -103,7 +100,7 @@ public class RecordsAPI extends RMModelRequest
* </ul>
*
*/
public FilePlanComponent fileRecord(RecordBodyFile recordBodyFile, String recordId) throws Exception
public Record fileRecord(RecordBodyFile recordBodyFile, String recordId) throws Exception
{
mandatoryObject("recordBodyFile", recordBodyFile);
mandatoryString("recordId", recordId);
@@ -116,7 +113,7 @@ public class RecordsAPI extends RMModelRequest
*
* @param recordBodyFile The properties where to file the record
* @param recordId The id of the record to file
* @return The {@link FilePlanComponent} with the given properties
* @return The {@link Record} with the given properties
* @throws Exception for the following cases:
* <ul>
* <li>Invalid parameter: {@code recordBodyFile} is not a valid format,{@code recordId} is not a record</li>
@@ -128,12 +125,12 @@ public class RecordsAPI extends RMModelRequest
* </ul>
*
*/
public FilePlanComponent fileRecord(RecordBodyFile recordBodyFile, String recordId, String parameters) throws Exception
public Record fileRecord(RecordBodyFile recordBodyFile, String recordId, String parameters) throws Exception
{
mandatoryObject("requestBodyFile", recordBodyFile);
mandatoryString("recordId", recordId);
return getRMRestWrapper().processModel(FilePlanComponent.class, requestWithBody(
return getRmRestWrapper().processModel(Record.class, requestWithBody(
POST,
toJson(recordBodyFile),
"/records/{recordId}/file?{parameters}",
@@ -141,5 +138,106 @@ public class RecordsAPI extends RMModelRequest
parameters
));
}
}
/**
* Deletes a record.
*
* @param recordId The identifier of a record
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code recordId}</li>
* <li>{@code recordId} does not exist</li>
* <li>{@code recordId} is locked and cannot be deleted</li>
* </ul>
*/
public void deleteRecord(String recordId)
{
mandatoryString("recordId", recordId);
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"records/{recordId}",
recordId
));
}
/**
* see {@link #getRecord(String, String)}
*/
public Record getRecord(String recordId)
{
mandatoryString("recordId", recordId);
return getRecord(recordId, EMPTY);
}
/**
* Gets a record.
*
* @param recordId The identifier of a record
* @param parameters The URL parameters to add
* @return The {@link Record} for the given {@code recordId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code recordId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code recordId}</li>
* <li>{@code recordId} does not exist</li>
* </ul>
*/
public Record getRecord(String recordId, String parameters)
{
mandatoryString("recordId", recordId);
return getRmRestWrapper().processModel(Record.class, simpleRequest(
GET,
"records/{recordId}?{parameters}",
recordId,
parameters
));
}
/**
* see {@link #updateRecord(Record, String, String)
*/
public Record updateRecord(Record recordModel, String recordId) throws Exception
{
mandatoryObject("recordModel", recordModel);
mandatoryString("recordId", recordId);
return updateRecord(recordModel, recordId, EMPTY);
}
/**
* Updates a record.
*
* @param recordModel The record model which holds the information
* @param recordId The identifier of a record
* @param parameters The URL parameters to add
* @param returns The updated {@link Record}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code recordId} is not a valid format or {@code recordModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code recordId}</li>
* <li>{@code recordId} does not exist</li>
* <li>the updated name clashes with an existing record in the current parent folder</li>
* <li>model integrity exception, including file name with invalid characters</li>
* </ul>
*/
public Record updateRecord(Record recordModel, String recordId, String parameters) throws Exception
{
mandatoryObject("recordModel", recordModel);
mandatoryString("recordId", recordId);
return getRmRestWrapper().processModel(Record.class, requestWithBody(
PUT,
toJson(recordModel),
"records/{recordId}?{parameters}",
recordId,
parameters
));
}
}

View File

@@ -0,0 +1,125 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.GET;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.transfer.Transfer;
import org.alfresco.rest.rm.community.model.transfer.TransferChildCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* Transfer REST API Wrapper
*
* @author Silviu Dinuta
* @since 2.6
*/
public class TransferAPI extends RMModelRequest
{
/**
* @param rmRestWrapper
*/
public TransferAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* see {@link #getTransfer(String, String)}
*/
public Transfer getTransfer(String transferId)
{
mandatoryString("transferId", transferId);
return getTransfer(transferId, EMPTY);
}
/**
* Gets a transfer.
*
* @param transferId The identifier of a transfer
* @param parameters The URL parameters to add
* @return The {@link Transfer} for the given {@code transferId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code transferId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code transferId}</li>
* <li>{@code transferId} does not exist</li>
* </ul>
*/
public Transfer getTransfer(String transferId, String parameters)
{
mandatoryString("transferId", transferId);
return getRmRestWrapper().processModel(Transfer.class, simpleRequest(
GET,
"/transfers/{transferId}?{parameters}",
transferId,
parameters
));
}
/**
* see {@link #getTransfersChildren(String, String)}
*/
public TransferChildCollection getTransfersChildren(String transferId)
{
mandatoryString("transferId", transferId);
return getTransfersChildren(transferId, EMPTY);
}
/**
* Gets the children (record folder or record) of a transfer.
*
* @param transferId The identifier of a transfer
* @param parameters The URL parameters to add
* @return The {@link TransferChildCollection} for the given {@code transferId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code transferId}</li>
* <li>{@code filePlanId} does not exist</li>
*</ul>
*/
public TransferChildCollection getTransfersChildren(String transferId, String parameters)
{
mandatoryString("transferId", transferId);
return getRmRestWrapper().processModels(TransferChildCollection.class, simpleRequest(
GET,
"transfers/{filePlanId}/children?{parameters}",
transferId,
parameters
));
}
}

View File

@@ -0,0 +1,172 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.PUT;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.transfer.TransferCollection;
import org.alfresco.rest.rm.community.model.transfercontainer.TransferContainer;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* Transfer Container REST API Wrapper
*
* @author Silviu Dinuta
* @since 2.6
*/
public class TransferContainerAPI extends RMModelRequest
{
/**
* @param rmRestWrapper
*/
public TransferContainerAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* see {@link #getTransferContainer(String, String)}
*/
public TransferContainer getTransferContainer(String transferContainerId)
{
mandatoryString("transferContainerId", transferContainerId);
return getTransferContainer(transferContainerId, EMPTY);
}
/**
* Gets a transfer container.
*
* @param transferContainerId The identifier of a transfer container
* @param parameters The URL parameters to add
* @return The {@link TransferContainer} for the given {@code transferContainerId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code transferContainerId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code transferContainerId}</li>
* <li>{@code transferContainerId} does not exist</li>
* </ul>
*/
public TransferContainer getTransferContainer(String transferContainerId, String parameters)
{
mandatoryString("transferContainerId", transferContainerId);
return getRmRestWrapper().processModel(TransferContainer.class, simpleRequest(
GET,
"/transfer-containers/{transferContainerId}?{parameters}",
transferContainerId,
parameters
));
}
/**
* see {@link #updateTransferContainer(TransferContainer, String, String)
*/
public TransferContainer updateTransferContainer(TransferContainer transferContainerModel, String transferContainerId) throws Exception
{
mandatoryObject("transferContainerModel", transferContainerModel);
mandatoryString("transferContainerId", transferContainerId);
return updateTransferContainer(transferContainerModel, transferContainerId, EMPTY);
}
/**
* Updates a transfer container.
*
* @param transferContainerModel The transfer container model which holds the information
* @param transferContainerId The identifier of a transfer container
* @param parameters The URL parameters to add
* @param returns The updated {@link TransferContainer}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code transferContainerId} is not a valid format or {@code transferContainerModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code transferContainerId}</li>
* <li>{@code transferContainerId} does not exist</li>
* <li>the updated name clashes with an existing transfer container in the current file plan</li>
* <li>model integrity exception, including transfer container name with invalid characters</li>
* </ul>
*/
public TransferContainer updateTransferContainer(TransferContainer transferContainerModel, String transferContainerId, String parameters) throws Exception
{
mandatoryObject("transferContainerModel", transferContainerModel);
mandatoryString("transferContainerId", transferContainerId);
return getRmRestWrapper().processModel(TransferContainer.class, requestWithBody(
PUT,
toJson(transferContainerModel),
"transfer-containers/{transferContainerId}?{parameters}",
transferContainerId,
parameters
));
}
/**
* see {@link #getTransfers(String, String)}
*/
public TransferCollection getTransfers(String transferContainerId)
{
mandatoryString("transferContainerId", transferContainerId);
return getTransfers(transferContainerId, EMPTY);
}
/**
* Gets the children (transfers) of a transfer container.
*
* @param transferContainerId The identifier of a transfer container
* @param parameters The URL parameters to add
* @return The {@link TransferCollection} for the given {@code transferContainerId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code transferContainerId}</li>
* <li>{@code filePlanId} does not exist</li>
*</ul>
*/
public TransferCollection getTransfers(String transferContainerId, String parameters)
{
mandatoryString("transferContainerId", transferContainerId);
return getRmRestWrapper().processModels(TransferCollection.class, simpleRequest(
GET,
"transfer-containers/{filePlanId}/transfers?{parameters}",
transferContainerId,
parameters
));
}
}

View File

@@ -0,0 +1,268 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
import static org.testng.Assert.fail;
import java.io.File;
import java.util.Iterator;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.alfresco.rest.rm.community.util.FilePlanComponentMixIn;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.http.ContentType;
/**
* Unfiled Container REST API Wrapper
*
* @author Tuna Aksoy
* @author Ana Bozianu
* @since 2.6
*/
public class UnfiledContainerAPI extends RMModelRequest
{
/**
* @param rmRestWrapper
*/
public UnfiledContainerAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* see {@link #getUnfiledContainer(String, String)}
*/
public UnfiledContainer getUnfiledContainer(String unfiledContainerId)
{
mandatoryString("unfiledContainerId", unfiledContainerId);
return getUnfiledContainer(unfiledContainerId, EMPTY);
}
/**
* Gets an unfiled record container.
*
* @param unfiledContainerId The identifier of a unfiled record container
* @param parameters The URL parameters to add
* @return The {@link UnfiledContainer} for the given {@code unfiledContainerId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code unfiledContainerId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code unfiledContainerId}</li>
* <li>{@code unfiledContainerId} does not exist</li>
* </ul>
*/
public UnfiledContainer getUnfiledContainer(String unfiledContainerId, String parameters)
{
mandatoryString("unfiledContainerId", unfiledContainerId);
return getRmRestWrapper().processModel(UnfiledContainer.class, simpleRequest(
GET,
"unfiled-containers/{unfiledContainerId}?{parameters}",
unfiledContainerId,
parameters
));
}
/**
* see {@link #getRootRecordCategories(String, String)}
*/
public UnfiledContainerChildCollection getUnfiledContainerChildren(String unfiledContainerId)
{
mandatoryString("unfiledContainerId", unfiledContainerId);
return getUnfiledContainerChildren(unfiledContainerId, EMPTY);
}
/**
* Gets the children of an unfiled records container
*
* @param unfiledContainerId The identifier of an unfiled records container
* @param parameters The URL parameters to add
* @return The {@link UnfiledContainerChildCollection} for the given {@code unfiledContainerId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code unfiledContainerId}</li>
* <li>{@code unfiledContainerId} does not exist</li>
*</ul>
*/
public UnfiledContainerChildCollection getUnfiledContainerChildren(String unfiledContainerId, String parameters)
{
mandatoryString("unfiledContainerId", unfiledContainerId);
return getRmRestWrapper().processModels(UnfiledContainerChildCollection.class, simpleRequest(
GET,
"unfiled-containers/{unfiledContainerId}/children?{parameters}",
unfiledContainerId,
parameters
));
}
/**
* see {@link #createUnfiledContainerChild(UnfiledContainerChild, String, String)}
*/
public UnfiledContainerChild createUnfiledContainerChild(UnfiledContainerChild unfiledContainerChildModel, String unfiledContainerId) throws Exception
{
mandatoryObject("unfiledContainerChildModel", unfiledContainerChildModel);
mandatoryString("unfiledContainerId", unfiledContainerId);
return createUnfiledContainerChild(unfiledContainerChildModel, unfiledContainerId, EMPTY);
}
/**
* Creates an unfiled container child. Can be a record or an unfiled record folder.
*
* @param unfiledContainerChildModel The unfiled container child model which holds the information
* @param unfiledContainerId The identifier of an unfiled container
* @param parameters The URL parameters to add
* @return The created {@link UnfiledContainerChild}
* @throws Exception for the following cases:
* <ul>
* <li>{@code unfiledContainerId} is not a valid format or {@code unfiledContainerChildModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code unfiledContainerId}</li>
* <li>{@code unfiledContainerId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public UnfiledContainerChild createUnfiledContainerChild(UnfiledContainerChild unfiledContainerChildModel, String unfiledContainerId, String parameters) throws Exception
{
mandatoryObject("unfiledContainerChildModel", unfiledContainerChildModel);
mandatoryString("unfiledContainerId", unfiledContainerId);
return getRmRestWrapper().processModel(UnfiledContainerChild.class, requestWithBody(
POST,
toJson(unfiledContainerChildModel),
"unfiled-containers/{unfiledContainerId}/children?{parameters}",
unfiledContainerId,
parameters
));
}
/**
* Create a record from file resource
*
* @param unfiledContainerChildModel {@link UnfiledContainerChild} for electronic record to be created
* @param unfiledContainerChildContent {@link File} pointing to the content of the electronic record to be created
* @param unfiledContainerId The identifier of a unfiled container
* @return newly created {@link UnfiledContainerChild}
* @throws Exception for invalid recordModel JSON strings
*/
public UnfiledContainerChild uploadRecord(UnfiledContainerChild unfiledContainerChildModel, String unfiledContainerId, File unfiledContainerChildContent) throws Exception
{
mandatoryObject("unfiledContainerChildModel", unfiledContainerChildModel);
mandatoryObject("unfiledContainerChildContent", unfiledContainerChildContent);
mandatoryString("unfiledContainerId", unfiledContainerId);
if (!unfiledContainerChildModel.getNodeType().equals(CONTENT_TYPE))
{
fail("Only electronic records are supported");
}
/*
* For file uploads nodeBodyCreate is ignored hence can't be used. Append all Record fields
* to the request.
*/
RequestSpecBuilder builder = getRmRestWrapper().configureRequestSpec();
JsonNode root = new ObjectMapper().readTree(toJson(unfiledContainerChildModel, Record.class, FilePlanComponentMixIn.class));
// add request fields
Iterator<String> fieldNames = root.fieldNames();
while (fieldNames.hasNext())
{
String fieldName = fieldNames.next();
builder.addMultiPart(fieldName, root.get(fieldName).asText(), ContentType.JSON.name());
}
builder.addMultiPart("filedata", unfiledContainerChildContent, ContentType.BINARY.name());
// create node with given content
return createUnfiledContainerChild(unfiledContainerChildModel, unfiledContainerId);
}
/**
* see {@link #updateUnfiledContainer(UnfiledContainer, String, String)
*/
public UnfiledContainer updateUnfiledContainer(UnfiledContainer unfiledContainerModel, String unfiledContainerId) throws Exception
{
mandatoryObject("unfiledContainerModel", unfiledContainerModel);
mandatoryString("unfiledContainerId", unfiledContainerId);
return updateUnfiledContainer(unfiledContainerModel, unfiledContainerId, EMPTY);
}
/**
* Updates an unfiled record container
*
* @param unfiledContainerModel The unfiled record container model which holds the information
* @param unfiledContainerId The identifier of an unfiled record container
* @param parameters The URL parameters to add
* @param returns The updated {@link UnfiledContainer}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code unfiledContainerId} is not a valid format or {@code unfiledContainerModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code unfiledContainerId}</li>
* <li>{@code unfiledContainerId} does not exist</li>
* <li>the updated name clashes with an existing root category of special container in the current fileplan</li>
* <li>model integrity exception, including file name with invalid characters</li>
* </ul>
*/
public UnfiledContainer updateUnfiledContainer(UnfiledContainer unfiledContainerModel, String unfiledContainerId, String parameters) throws Exception
{
mandatoryObject("unfiledContainerModel", unfiledContainerModel);
mandatoryString("unfiledContainerId", unfiledContainerId);
return getRmRestWrapper().processModel(UnfiledContainer.class, requestWithBody(
PUT,
toJson(unfiledContainerModel),
"unfiled-containers/{unfiledContainerId}?{parameters}",
unfiledContainerId,
parameters
));
}
}

View File

@@ -0,0 +1,292 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.gscore.api;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.DELETE;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
import static org.testng.Assert.fail;
import java.io.File;
import java.util.Iterator;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildCollection;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledRecordFolder;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
import org.alfresco.rest.rm.community.util.FilePlanComponentMixIn;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.http.ContentType;
/**
* Unfiled Record Folders REST API Wrapper
*
* @author Ramona Popa
* @since 2.6
*/
public class UnfiledRecordFolderAPI extends RMModelRequest
{
/**
* @param rmRestWrapper
*/
public UnfiledRecordFolderAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* see {@link #getUnfiledRecordFolder(String, String)}
*/
public UnfiledRecordFolder getUnfiledRecordFolder(String unfiledRecordFolderId)
{
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return getUnfiledRecordFolder(unfiledRecordFolderId, EMPTY);
}
/**
* Gets an unfiled record folder.
*
* @param unfiledRecordFolderId The identifier of a unfiled record folder
* @param parameters The URL parameters to add
* @return The {@link UnfiledRecordFolder} for the given {@code unfiledRecordFolderId}
* @throws Exception for the following cases:
* <ul>
* <li>{@code unfiledRecordFolderId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code unfiledRecordFolderId}</li>
* <li>{@code unfiledRecordFolderId} does not exist</li>
* </ul>
*/
public UnfiledRecordFolder getUnfiledRecordFolder(String unfiledRecordFolderId, String parameters)
{
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return getRmRestWrapper().processModel(UnfiledRecordFolder.class, simpleRequest(
GET,
"unfiled-record-folders/{unfiledRecordFolderId}?{parameters}",
unfiledRecordFolderId,
parameters
));
}
/**
* see {@link #getUnfiledRecordFolderChildren(String, String)}
*/
public UnfiledContainerChildCollection getUnfiledRecordFolderChildren(String unfiledRecordFolderId)
{
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return getUnfiledRecordFolderChildren(unfiledRecordFolderId, EMPTY);
}
/**
* Gets the children of an unfiled record folder
*
* @param unfiledRecordFolderId The identifier of an unfiled records folder
* @param parameters The URL parameters to add
* @return The {@link UnfiledRecordFolderChildCollection} for the given {@code unfiledRecordFolderId}
* @throws Exception for the following cases:
* <ul>
* <li>authentication fails</li>
* <li>current user does not have permission to read {@code unfiledRecordFolderId}</li>
* <li>{@code unfiledRecordFolderId} does not exist</li>
*</ul>
*/
public UnfiledContainerChildCollection getUnfiledRecordFolderChildren(String unfiledRecordFolderId, String parameters)
{
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return getRmRestWrapper().processModels(UnfiledContainerChildCollection.class, simpleRequest(
GET,
"unfiled-record-folders/{unfiledRecordFolderId}/children?{parameters}",
unfiledRecordFolderId,
parameters
));
}
/**
* see {@link #createUnfiledRecordFolderChild(UnfiledContainerChild, String, String)}
*/
public UnfiledContainerChild createUnfiledRecordFolderChild(UnfiledContainerChild unfiledRecordFolderChildModel, String unfiledRecordFolderId) throws Exception
{
mandatoryObject("unfiledRecordFolderChildModel", unfiledRecordFolderChildModel);
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return createUnfiledRecordFolderChild(unfiledRecordFolderChildModel, unfiledRecordFolderId, EMPTY);
}
/**
* Creates an unfiled record folder child. Can be a record or an unfiled record folder.
*
* @param unfiledRecordFolderChildModel The unfiled folder child model which holds the information
* @param unfiledRecordFolderId The identifier of an unfiled folder
* @param parameters The URL parameters to add
* @return The created {@link UnfiledRecordFolderChild}
* @throws Exception for the following cases:
* <ul>
* <li>{@code unfiledRecordFolderId} is not a valid format or {@code unfiledRecordFolderChildModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code unfiledRecordFolderId}</li>
* <li>{@code unfiledRecordFolderId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public UnfiledContainerChild createUnfiledRecordFolderChild(UnfiledContainerChild unfiledRecordFolderChildModel, String unfiledRecordFolderId, String parameters) throws Exception
{
mandatoryObject("unfiledRecordFolderChildModel", unfiledRecordFolderChildModel);
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return getRmRestWrapper().processModel(UnfiledContainerChild.class, requestWithBody(
POST,
toJson(unfiledRecordFolderChildModel),
"unfiled-record-folders/{unfiledRecordFolderId}/children?{parameters}",
unfiledRecordFolderId,
parameters
));
}
/**
* Create a record from file resource
*
* @param unfiledRecordFolderChildModel {@link UnfiledContainerChild} for electronic record to be created
* @param unfiledRecordFolderChildContent {@link File} pointing to the content of the electronic record to be created
* @param unfiledRecordFolderId The identifier of a unfiled record folder
* @return newly created {@link UnfiledContainerChild}
* @throws Exception for invalid recordModel JSON strings
*/
public UnfiledContainerChild uploadRecord(UnfiledContainerChild unfiledRecordFolderChildModel, String unfiledRecordFolderId, File unfiledRecordFolderChildContent) throws Exception
{
mandatoryObject("unfiledRecordFolderChildModel", unfiledRecordFolderChildModel);
mandatoryObject("unfiledRecordFolderChildContent", unfiledRecordFolderChildContent);
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
if (!unfiledRecordFolderChildModel.getNodeType().equals(CONTENT_TYPE))
{
fail("Only electronic records are supported");
}
/*
* For file uploads nodeBodyCreate is ignored hence can't be used. Append all Record fields
* to the request.
*/
RequestSpecBuilder builder = getRmRestWrapper().configureRequestSpec();
JsonNode root = new ObjectMapper().readTree(toJson(unfiledRecordFolderChildModel, Record.class, FilePlanComponentMixIn.class));
// add request fields
Iterator<String> fieldNames = root.fieldNames();
while (fieldNames.hasNext())
{
String fieldName = fieldNames.next();
builder.addMultiPart(fieldName, root.get(fieldName).asText(), ContentType.JSON.name());
}
builder.addMultiPart("filedata", unfiledRecordFolderChildContent, ContentType.BINARY.name());
// create node with given content
return createUnfiledRecordFolderChild(unfiledRecordFolderChildModel, unfiledRecordFolderId);
}
/**
* see {@link #updateUnfiledRecordFolder(UnfiledRecordFolder, String, String)
*/
public UnfiledRecordFolder updateUnfiledRecordFolder(UnfiledRecordFolder unfiledRecordFolderModel, String unfiledRecordFolderId) throws Exception
{
mandatoryObject("unfiledRecordFolderModel", unfiledRecordFolderModel);
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return updateUnfiledRecordFolder(unfiledRecordFolderModel, unfiledRecordFolderId, EMPTY);
}
/**
* Updates an unfiled record folder
*
* @param unfiledRecordFolderModel The unfiled record folder model which holds the information
* @param unfiledRecordFolderId The identifier of an unfiled record folder
* @param parameters The URL parameters to add
* @param returns The updated {@link UnfiledRecordFolder}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code unfiledRecordFolderId} is not a valid format or {@code unfiledRecordFolderModel} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code unfiledRecordFolderId}</li>
* <li>{@code unfiledRecordFolderId} does not exist</li>
* <li>the updated name clashes with an existing root category of special container in the current fileplan</li>
* <li>model integrity exception, including file name with invalid characters</li>
* </ul>
*/
public UnfiledRecordFolder updateUnfiledRecordFolder(UnfiledRecordFolder unfiledRecordFolderModel, String unfiledRecordFolderId, String parameters) throws Exception
{
mandatoryObject("unfiledRecordFolderModel", unfiledRecordFolderModel);
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
return getRmRestWrapper().processModel(UnfiledRecordFolder.class, requestWithBody(
PUT,
toJson(unfiledRecordFolderModel),
"unfiled-record-folders/{unfiledRecordFolderId}?{parameters}",
unfiledRecordFolderId,
parameters
));
}
/**
* Deletes an unfiled record folder.
*
* @param unfiledRecordFolderId The identifier of a unfiled record folder
* @throws Exception for the following cases:
* <ul>
* <li>{@code unfiledRecordFolderId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code unfiledRecordFolderId}</li>
* <li>{@code unfiledRecordFolderId} does not exist</li>
* <li>{@code unfiledRecordFolderId} is locked and cannot be deleted</li>
* </ul>
*/
public void deleteUnfiledRecordFolder(String unfiledRecordFolderId)
{
mandatoryString("unfiledRecordFolderId", unfiledRecordFolderId);
getRmRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"unfiled-record-folders/{recordFolderId}",
unfiledRecordFolderId
));
}
}

View File

@@ -1,351 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.igCoreAPI;
import static com.jayway.restassured.RestAssured.basic;
import static com.jayway.restassured.RestAssured.given;
import static org.alfresco.rest.core.RestRequest.requestWithBody;
import static org.alfresco.rest.core.RestRequest.simpleRequest;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryString;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJsonElectronicRecord;
import static org.apache.commons.lang3.StringUtils.EMPTY;
import static org.springframework.http.HttpMethod.DELETE;
import static org.springframework.http.HttpMethod.GET;
import static org.springframework.http.HttpMethod.POST;
import static org.springframework.http.HttpMethod.PUT;
import static org.testng.Assert.fail;
import java.io.File;
import java.util.Iterator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.http.ContentType;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentsCollection;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* File plan component REST API Wrapper
*
* @author Tuna Aksoy
* @since 2.6
*/
public class FilePlanComponentAPI extends RMModelRequest
{
/**
* Constructor
*
* @param restWrapper
*/
public FilePlanComponentAPI(RMRestWrapper rmRestWrapper)
{
super(rmRestWrapper);
}
/**
* Get a file plan component
*
* @param filePlanComponentId The id of the file plan component to get
* @return The {@link FilePlanComponent} for the given file plan component id
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>{@code fileplanComponentId} does not exist</li>
* </ul>
*/
public FilePlanComponent getFilePlanComponent(String filePlanComponentId) throws Exception
{
mandatoryString("filePlanComponentId", filePlanComponentId);
return getFilePlanComponent(filePlanComponentId, EMPTY);
}
/**
* Get a file plan component
*
* @param filePlanComponentId The id of the file plan component to get
* @param parameters The URL parameters to add
* @return The {@link FilePlanComponent} for the given file plan component id
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>{@code fileplanComponentId} does not exist</li>
* </ul>
*/
public FilePlanComponent getFilePlanComponent(String filePlanComponentId, String parameters) throws Exception
{
mandatoryString("filePlanComponentId", filePlanComponentId);
return getRMRestWrapper().processModel(FilePlanComponent.class, simpleRequest(
GET,
"fileplan-components/{fileplanComponentId}?{parameters}",
filePlanComponentId,
parameters
));
}
/**
* List child components of a file plan component
*
* @param filePlanComponentId The id of the file plan component of which to get child components
* @return The {@link FilePlanComponent} for the given file plan component id
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>{@code fileplanComponentId} does not exist</li>
* </ul>
*/
public FilePlanComponentsCollection listChildComponents(String filePlanComponentId) throws Exception
{
mandatoryString("filePlanComponentId", filePlanComponentId);
return getRMRestWrapper().processModels(FilePlanComponentsCollection.class, simpleRequest(
GET,
"fileplan-components/{fileplanComponentId}/children",
filePlanComponentId
));
}
/**
* List child components of a file plan component
* @param parameters The URL parameters to add
* @param filePlanComponentId The id of the file plan component of which to get child components
* @return The {@link FilePlanComponent} for the given file plan component id
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>{@code fileplanComponentId} does not exist</li>
*</ul>
*/
public FilePlanComponentsCollection listChildComponents(String filePlanComponentId, String parameters) throws Exception
{
mandatoryString("filePlanComponentId", filePlanComponentId);
return getRMRestWrapper().processModels(FilePlanComponentsCollection.class, simpleRequest(
GET,
"fileplan-components/{fileplanComponentId}/children?{parameters}",
filePlanComponentId,parameters
));
}
/**
* Creates a file plan component with the given properties under the parent node with the given id
*
* @param filePlanComponentModel The properties of the file plan component to be created
* @param parentId The id of the parent where the new file plan component should be created
* @return The {@link FilePlanComponent} with the given properties
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code fileplanComponentId}</li>
* <li>{@code fileplanComponentId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public FilePlanComponent createFilePlanComponent(FilePlanComponent filePlanComponentModel, String parentId) throws Exception
{
mandatoryObject("filePlanComponentProperties", filePlanComponentModel);
mandatoryString("parentId", parentId);
return createFilePlanComponent(filePlanComponentModel, parentId, EMPTY);
}
/**
* Creates a file plan component with the given properties under the parent node with the given id
*
* @param filePlanComponentModel The properties of the file plan component to be created
* @param parameters The URL parameters to add
* @param parentId The id of the parent where the new file plan component should be created
* @return The {@link FilePlanComponent} with the given properties
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to add children to {@code fileplanComponentId}</li>
* <li>{@code fileplanComponentId} does not exist</li>
* <li>new name clashes with an existing node in the current parent container</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public FilePlanComponent createFilePlanComponent(FilePlanComponent filePlanComponentModel, String parentId, String parameters) throws Exception
{
mandatoryObject("filePlanComponentProperties", filePlanComponentModel);
mandatoryString("parentId", parentId);
return getRMRestWrapper().processModel(FilePlanComponent.class, requestWithBody(
POST,
toJson(filePlanComponentModel),
"fileplan-components/{fileplanComponentId}/children?{parameters}",
parentId,
parameters
));
}
/**
* Create electronic record from file resource
* @param electronicRecordModel {@link FilePlanComponent} for electronic record to be created
* @param fileName the name of the resource file
* @param parentId parent container id
* @return newly created {@link FilePlanComponent}
* @throws Exception if operation failed
*/
public FilePlanComponent createElectronicRecord(FilePlanComponent electronicRecordModel, String fileName, String parentId) throws Exception
{
return createElectronicRecord(electronicRecordModel, new File(Resources.getResource(fileName).getFile()), parentId);
}
/**
* Create electronic record from file resource
*
* @param electronicRecordModel {@link FilePlanComponent} for electronic record to be created
* @param recordContent {@link File} pointing to the content of the electronic record to be created
* @param parentId parent container id
* @return newly created {@link FilePlanComponent}
* @throws Exception for invalid electronicRecordModel JSON strings
*/
public FilePlanComponent createElectronicRecord(FilePlanComponent electronicRecordModel, File recordContent,
String parentId) throws Exception
{
mandatoryObject("electronicRecordModel", electronicRecordModel);
mandatoryString("parentId", parentId);
if (!electronicRecordModel.getNodeType().equals(CONTENT_TYPE))
{
fail("Only electronic records are supported");
}
/*
* For file uploads nodeBodyCreate is ignored hence can't be used. Append all FilePlanComponent fields
* to the request.
*/
RequestSpecBuilder builder = getRMRestWrapper().configureRequestSpec();
JsonNode root = new ObjectMapper().readTree(toJsonElectronicRecord(electronicRecordModel));
// add request fields
Iterator<String> fieldNames = root.fieldNames();
while (fieldNames.hasNext())
{
String fieldName = fieldNames.next();
builder.addMultiPart(fieldName, root.get(fieldName).asText(), ContentType.JSON.name());
}
builder.addMultiPart("filedata", recordContent, ContentType.BINARY.name());
// create node with given content
return createFilePlanComponent(electronicRecordModel, parentId);
}
/**
* Updates a file plan component
*
* @param filePlanComponentModel The properties to be updated
* @param filePlanComponentId The id of the file plan component which will be updated
* @param returns The updated {@link FilePlanComponent}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code fileplanComponentId} is not a valid format or {@code filePlanComponentProperties} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code fileplanComponentId}</li>
* <li>{@code fileplanComponentId} does not exist</li>
* <li>the updated name clashes with an existing node in the current parent folder</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public FilePlanComponent updateFilePlanComponent(FilePlanComponent filePlanComponentModel, String filePlanComponentId) throws Exception
{
mandatoryObject("filePlanComponentProperties", filePlanComponentModel);
mandatoryString("filePlanComponentId", filePlanComponentId);
return updateFilePlanComponent(filePlanComponentModel, filePlanComponentId, EMPTY);
}
/**
* Updates a file plan component
*
* @param filePlanComponent The properties to be updated
* @param parameters The URL parameters to add
* @param filePlanComponentId The id of the file plan component which will be updated
* @param returns The updated {@link FilePlanComponent}
* @throws Exception for the following cases:
* <ul>
* <li>the update request is invalid or {@code fileplanComponentId} is not a valid format or {@code filePlanComponentProperties} is invalid</li>
* <li>authentication fails</li>
* <li>current user does not have permission to update {@code fileplanComponentId}</li>
* <li>{@code fileplanComponentId} does not exist</li>
* <li>the updated name clashes with an existing node in the current parent folder</li>
* <li>model integrity exception, including node name with invalid characters</li>
* </ul>
*/
public FilePlanComponent updateFilePlanComponent(FilePlanComponent filePlanComponent, String filePlanComponentId, String parameters) throws Exception
{
mandatoryObject("filePlanComponentProperties", filePlanComponent);
mandatoryString("filePlanComponentId", filePlanComponentId);
return getRMRestWrapper().processModel(FilePlanComponent.class, requestWithBody(
PUT,
toJson(filePlanComponent),
"fileplan-components/{fileplanComponentId}?{parameters}",
filePlanComponentId,
parameters
));
}
/**
* Delete file plan component
*
* @param filePlanComponentId The id of the file plan component to be deleted
* @throws Exception for the following cases:
* <ul>
* <li>{@code fileplanComponentId} is not a valid format</li>
* <li>authentication fails</li>
* <li>current user does not have permission to delete {@code fileplanComponentId}</li>
* <li>{@code fileplanComponentId} does not exist</li>
* <li>{@code fileplanComponentId} is locked and cannot be deleted</li>
* </ul>
*/
public void deleteFilePlanComponent(String filePlanComponentId) throws Exception
{
mandatoryString("filePlanComponentId", filePlanComponentId);
getRMRestWrapper().processEmptyModel(simpleRequest(
DELETE,
"fileplan-components/{fileplanComponentId}",
filePlanComponentId
));
}
}

View File

@@ -1,111 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.requests.igCoreAPI;
import static java.lang.Integer.parseInt;
import static java.lang.String.format;
import com.jayway.restassured.RestAssured;
import org.alfresco.rest.core.RMRestProperties;
import org.alfresco.rest.core.RMRestWrapper;
import org.alfresco.rest.rm.community.requests.RMModelRequest;
/**
* Defines the entire IG Core API
* {@link http://host:port/ig-api-explorer} select "IG Core API"
*
* @author Tuna Aksoy
* @since 2.6
*/
public class RestIGCoreAPI extends RMModelRequest
{
/**
* Constructor
*
* @param rmRestWrapper RM REST Wrapper
* @param rmRestProperties RM REST Properties
*/
public RestIGCoreAPI(RMRestWrapper rmRestWrapper, RMRestProperties rmRestProperties)
{
super(rmRestWrapper);
RestAssured.baseURI = format("%s://%s", rmRestProperties.getScheme(), rmRestProperties.getServer());
RestAssured.port = parseInt(rmRestProperties.getPort());
RestAssured.basePath = rmRestProperties.getRestRmPath();
restWrapper.configureRequestSpec().setBasePath(RestAssured.basePath);
}
/**
* Provides DSL on all REST calls under <code>ig-sites/rm/...</code> API path
*
* @return {@link RMSiteAPI}
*/
public RMSiteAPI usingRMSite()
{
return new RMSiteAPI(getRMRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>fileplan-components/...</code> API path
*
* @return {@link FilePlanComponentAPI}
*/
public FilePlanComponentAPI usingFilePlanComponents()
{
return new FilePlanComponentAPI(getRMRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>records/...</code> API path
*
* @return {@link FilePlanComponentAPI}
*/
public RecordsAPI usingRecords()
{
return new RecordsAPI(getRMRestWrapper());
}
/**
* Provides DSL on all REST calls under <code>files/...</code> API path
*
* @return {@link FilesAPI}
*/
public FilesAPI usingFiles()
{
return new FilesAPI(getRMRestWrapper());
}
/**
* Provides DSL for RM user management API
*
* @return {@link RMUserAPI}
*/
public RMUserAPI usingRMUser()
{
return new RMUserAPI(getRMRestWrapper());
}
}

View File

@@ -28,10 +28,10 @@ package org.alfresco.rest.rm.community.util;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.record.RecordProperties;
/**
* Mix class for FilePlanComponent POJO class
* Mix class for Record POJO class
* Mix-in annotations are: a way to associate annotations with classes
* without modifying (target) classes themselves.
*
@@ -45,6 +45,5 @@ public abstract class FilePlanComponentMixIn
* Its properties are instead included as properties of its containing Object
*/
@JsonUnwrapped
abstract FilePlanComponentProperties getProperties();
abstract RecordProperties getProperties();
}

View File

@@ -26,12 +26,12 @@
*/
package org.alfresco.rest.rm.community.util;
import static org.alfresco.rest.rm.community.util.ParameterCheck.mandatoryObject;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
/**
* Utility class for creating the json object
*
@@ -41,51 +41,48 @@ import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent
public class PojoUtility
{
/**
* Converting object to JSON string
*
* @param model The java object model to convert
* see {@link #toJson(Object, Class, Class)}
*/
public static String toJson(Object model)
{
ObjectMapper mapper = new ObjectMapper();
//include only values that differ from default settings to be included
mapper.setSerializationInclusion(Include.NON_DEFAULT);
try
{
//return the json object
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model);
}
catch (JsonProcessingException e)
{
return e.toString();
}
mandatoryObject("model", model);
return toJson(model, null, null);
}
/**
* Converting object to JSON string for electronic records
* Converting object to JSON string
*
* @param model The java object model to convert
* @throws JsonProcessingException Throws exceptions if the given object doesn't match to the POJO class model
* @param target Class (or interface) whose annotations to effectively override
* @param mixinSource Class (or interface) whose annotations are to be "added" to target's annotations, overriding as necessary
* @return The converted java object as JSON string
* @throws JsonProcessingException Throws exceptions if the given object doesn't match to the POJO class model
*/
public static String toJsonElectronicRecord(Object model)
public static String toJson(Object model, Class<?> target, Class<?> mixinSource)
{
mandatoryObject("model", model);
ObjectMapper mapper = new ObjectMapper();
//inject the "mix-in" annotations from FilePlanComponentMix to
// FilePlanComponent POJO class when converting to json
mapper.addMixIn(FilePlanComponent.class, FilePlanComponentMixIn.class);
if (target != null && mixinSource != null)
{
//inject the "mix-in" annotations from FilePlanComponentMix to
// FilePlanComponent POJO class when converting to json
mapper.addMixIn(target, mixinSource);
}
//include only values that differ from default settings to be included
mapper.setSerializationInclusion(Include.NON_DEFAULT);
//return the json object
try
{
//return the json object
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(model);
}
catch (JsonProcessingException e)
catch (JsonProcessingException error)
{
return e.toString();
return error.toString();
}
}
}

View File

@@ -33,15 +33,15 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentReviewPeriod;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
/**
* Utility class for serializing the Review Period type
* Utility class for serializing @{FilePlanComponentReviewPeriod}
*
* @author Rodica Sutu
* @since 2.6
*/
public class ReviewPeriodSerializer extends JsonSerializer<FilePlanComponentReviewPeriod>
public class ReviewPeriodSerializer extends JsonSerializer<ReviewPeriod>
{
/**
* @param value The Review Period value that is being serialized.
@@ -51,7 +51,7 @@ public class ReviewPeriodSerializer extends JsonSerializer<FilePlanComponentRevi
* @throws JsonProcessingException
*/
@Override
public void serialize(FilePlanComponentReviewPeriod value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
public void serialize(ReviewPeriod value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
{
//create the custom string value for the Review Period type
gen.writeString(new StringBuilder().append(value.getPeriodType()).append("|").append(value.getExpression()).toString());

View File

@@ -1,2 +1,2 @@
alfresco.server=localhost
rest.rmPath=alfresco/api/-default-/public/ig/versions/1
rest.rmPath=alfresco/api/-default-/public/gs/versions/1

View File

@@ -26,16 +26,20 @@
*/
package org.alfresco.rest.rm.community.base;
import static org.alfresco.rest.rm.community.base.TestData.CATEGORY_TITLE;
import static org.alfresco.rest.rm.community.base.TestData.FOLDER_TITLE;
import static lombok.AccessLevel.PROTECTED;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_CATEGORY_TITLE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_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.ASPECTS_CLOSED_RECORD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAspects.ASPECTS_COMPLETED_RECORD;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createFilePlanComponentModel;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordCategoryChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordCategoryModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createUnfiledContainerChildModel;
import static org.alfresco.rest.rm.community.utils.RMSiteUtil.createStandardRMSiteModel;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.CREATED;
@@ -47,10 +51,18 @@ import java.util.List;
import org.alfresco.rest.RestTest;
import org.alfresco.rest.core.RestAPIFactory;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RMSiteAPI;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderProperties;
import org.alfresco.rest.rm.community.model.transfercontainer.TransferContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.utility.data.DataUser;
import org.alfresco.utility.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
@@ -58,8 +70,10 @@ import org.springframework.http.HttpStatus;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import lombok.Getter;
/**
* Base class for all IG REST API Tests
* Base class for all GS REST API Tests
*
* @author Kristijan Conkas
* @author Tuna Aksoy
@@ -68,31 +82,13 @@ import org.testng.annotations.DataProvider;
public class BaseRMRestTest extends RestTest
{
@Autowired
@Getter (value = PROTECTED)
private RestAPIFactory restAPIFactory;
@Autowired
@Getter (value = PROTECTED)
private DataUser dataUser;
/**
* Gets the REST API Factory
*
* @return the restAPIFactory The REST API Factory
*/
protected RestAPIFactory getRestAPIFactory()
{
return this.restAPIFactory;
}
/**
* Gets the data user
*
* @return the dataUser The data user
*/
protected DataUser getDataUser()
{
return this.dataUser;
}
/**
* Asserts the given status code
*
@@ -100,7 +96,7 @@ public class BaseRMRestTest extends RestTest
*/
protected void assertStatusCode(HttpStatus statusCode)
{
restAPIFactory.getRmRestWrapper().assertStatusCodeIs(statusCode);
getRestAPIFactory().getRmRestWrapper().assertStatusCodeIs(statusCode);
}
/**
@@ -115,16 +111,16 @@ public class BaseRMRestTest extends RestTest
/** Valid root containers where electronic and non-electronic records can be created */
@DataProvider(name = "validRootContainers")
public Object[][] getValidRootContainers() throws Exception
public String[][] getValidRootContainers() throws Exception
{
return new Object[][]
return new String[][]
{
// an arbitrary record folder
{ createCategoryFolderInFilePlan() },
{ createCategoryFolderInFilePlan().getId(), RECORD_FOLDER_TYPE},
// unfiled records root
{ getFilePlanComponent(UNFILED_RECORDS_CONTAINER_ALIAS) },
{ UNFILED_RECORDS_CONTAINER_ALIAS, UNFILED_CONTAINER_TYPE},
// an arbitrary unfiled records folder
{ createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric()) }
{ createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId(), UNFILED_RECORD_FOLDER_TYPE }
};
}
@@ -145,7 +141,7 @@ public class BaseRMRestTest extends RestTest
*/
public void createRMSiteIfNotExists() throws Exception
{
RMSiteAPI rmSiteAPI = restAPIFactory.getRMSiteAPI();
RMSiteAPI rmSiteAPI = getRestAPIFactory().getRMSiteAPI();
// Check RM site doesn't exist
if (!rmSiteAPI.existsRMSite())
@@ -159,71 +155,162 @@ public class BaseRMRestTest extends RestTest
}
/**
* Helper method to create child category
* Helper method to create root category as the admin user
*
* @param user The user under whose privileges this structure is going to be created
* @param parentCategoryId The id of the parent category
* @param categoryName The name of the category
* @return The created category
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createCategory(UserModel user, String parentCategoryId, String categoryName) throws Exception
public RecordCategory createRootCategory(String categoryName) throws Exception
{
return createComponent(user, parentCategoryId, categoryName, RECORD_CATEGORY_TYPE, CATEGORY_TITLE);
return createRootCategory(getAdminUser(), categoryName, RECORD_CATEGORY_TITLE);
}
/**
* Helper method to create child category as the admin user
* Helper method to create root category
*
* @param parentCategoryId The id of the parent category
* @param userModel The user under whose privileges this structure is going to be created
* @param categoryName The name of the category
* @return The created category
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createCategory(String parentCategoryId, String categoryName) throws Exception
public RecordCategory createRootCategory(UserModel userModel, String categoryName) throws Exception
{
return createCategory(getAdminUser(), parentCategoryId, categoryName);
return createRootCategory(userModel, categoryName, RECORD_CATEGORY_TITLE);
}
/**
* Helper method to create child folder
* Helper method to create root category as the admin user
*
* @param categoryName The name of the category
* @param categoryTitle The title of the category
* @return The created category
* @throws Exception on unsuccessful component creation
*/
public RecordCategory createRootCategory(String categoryName, String categoryTitle) throws Exception
{
return createRootCategory(getAdminUser(), categoryName, categoryTitle);
}
/**
* Helper method to create root category
*
* @param userModel The user under whose privileges this structure is going to be created
* @param categoryName The name of the category
* @param categoryTitle The title of the category
* @return The created category
* @throws Exception on unsuccessful component creation
*/
public RecordCategory createRootCategory(UserModel userModel, String categoryName, String categoryTitle) throws Exception
{
RecordCategory recordCategoryModel = createRecordCategoryModel(categoryName, categoryTitle);
return getRestAPIFactory().getFilePlansAPI(userModel).createRootRecordCategory(recordCategoryModel, FILE_PLAN_ALIAS);
}
/**
* Helper method to create a record category child
*
* @param user The user under whose privileges the node is going to be created
* @param recordCategoryId The id of the record category
* @param name The name of the record category child
* @param type The type of the record category child
* @param title The title of the record category child
* @return The created {@link RecordCategoryChild}
* @throws Exception {@link RecordCategoryAPI#createRecordCategoryChild(RecordCategoryChild, String)}
*/
public RecordCategoryChild createRecordCategoryChild(UserModel user, String recordCategoryId, String name, String type) throws Exception
{
RecordCategoryChild recordCategoryChildModel = createRecordCategoryChildModel(name, type);
return getRestAPIFactory().getRecordCategoryAPI(user).createRecordCategoryChild(recordCategoryChildModel, recordCategoryId);
}
/**
* Helper method to create a record category child as the admin user
*
* @param user The user under whose privileges the node is going to be created
* @param recordCategoryId The id of the record category
* @param name The name of the record category child
* @param type The type of the record category child
* @param title The title of the record category child
* @return The created {@link RecordCategoryChild}
* @throws Exception {@link RecordCategoryAPI#createRecordCategoryChild(RecordCategoryChild, String)}
*/
public RecordCategoryChild createRecordCategoryChild(String recordCategoryId, String name, String type) throws Exception
{
return createRecordCategoryChild(getAdminUser(), recordCategoryId, name, type);
}
/**
* Helper method to create a record category as the admin user
*
* @param recordCategoryId The id of the record category
* @param name The name of the record category child
* @return The created {@link RecordCategoryChild}
* @throws Exception {@link RecordCategoryAPI#createRecordCategoryChild(RecordCategoryChild, String)}
*/
public RecordCategoryChild createRecordCategory(String recordCategoryId, String name) throws Exception
{
return createRecordCategoryChild(getAdminUser(), recordCategoryId, name, RECORD_CATEGORY_TYPE);
}
/**
* Helper method to create a record folder as the admin user
*
* @param recordCategoryId The id of the record category
* @param name The name of the record category child
* @return The created {@link RecordCategoryChild}
* @throws Exception {@link RecordCategoryAPI#createRecordCategoryChild(RecordCategoryChild, String)}
*/
public RecordCategoryChild createRecordFolder(String recordCategoryId, String name) throws Exception
{
return createRecordCategoryChild(getAdminUser(), recordCategoryId, name, RECORD_FOLDER_TYPE);
}
/**
* Helper method to create record folder
*
* @param user The user under whose privileges this structure is going to be created
* @param parentCategoryId The id of the parent category
* @param folderName The name of the category
* @return The created category
* @param recordCategoryId The id of the record category
* @param name The name of the folder
* @return The created folder
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createFolder(UserModel user, String parentCategoryId, String folderName) throws Exception
public RecordCategoryChild createFolder(UserModel user, String recordCategoryId, String name) throws Exception
{
return createComponent(user, parentCategoryId, folderName, RECORD_FOLDER_TYPE, FOLDER_TITLE);
RecordCategoryChild recordFolderModel = createRecordCategoryChildModel(name, RECORD_FOLDER_TYPE);
return getRestAPIFactory().getRecordCategoryAPI(user).createRecordCategoryChild(recordFolderModel, recordCategoryId);
}
/**
* Helper method to create child folder as the admin user
* Helper method to create record folder as the admin user
*
* @param parentCategoryId The id of the parent category
* @param folderName The name of the category
* @return The created category
* @param recordCategoryId The id of the record category
* @param name The name of the folder
* @return The created folder
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createFolder(String parentCategoryId, String folderName) throws Exception
public RecordCategoryChild createFolder(String recordCategoryId, String name) throws Exception
{
return createFolder(getAdminUser(), parentCategoryId, folderName);
return createFolder(getAdminUser(), recordCategoryId, name);
}
/**
* Helper method to create child unfiled record folder
*
* @param user The user under whose privileges this structure is going to be created
*@param user The user under whose privileges this structure is going to be created
* @param parentId The id of the parent folder
* @param folderName The name of the folder
* @param nodeType The child type
* @return The created folder
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createUnfiledRecordsFolder(UserModel user, String parentId, String folderName) throws Exception
public UnfiledContainerChild createUnfiledRecordsFolderChild(UserModel user, String parentId, String childName, String nodeType) throws Exception
{
return createComponent(user, parentId, folderName, UNFILED_RECORD_FOLDER_TYPE, FOLDER_TITLE);
UnfiledContainerChild childModel = createUnfiledContainerChildModel(childName, nodeType);
UnfiledContainerChild child = getRestAPIFactory().getUnfiledRecordFoldersAPI(user).createUnfiledRecordFolderChild(childModel, parentId);
assertStatusCode(CREATED);
return child;
}
/**
@@ -231,32 +318,46 @@ public class BaseRMRestTest extends RestTest
*
* @param parentId The id of the parent folder
* @param folderName The name of the folder
* @param nodeType The child type
* @return The created folder
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createUnfiledRecordsFolder(String parentId, String folderName) throws Exception
public UnfiledContainerChild createUnfiledRecordsFolderChild(String parentId, String childName, String nodeType) throws Exception
{
return createUnfiledRecordsFolder(getAdminUser(), parentId, folderName);
return createUnfiledRecordsFolderChild(getAdminUser(), parentId, childName, nodeType);
}
/**
* Helper method to create generic child component
* Helper method to create a child to an unfiled record container
*
* @param user user under whose privileges this structure is going to be created
* @param parentComponentId The id of the parent file plan component
* @param componentName The name of the file plan component
* @param componentType The type of the file plan component
* @param componentTitle The title of the file plan component
* @return The created file plan component
* @throws Exception
* @param user The user under whose privileges this structure is going to be created
* @param parentId The id of the parent container
* @param childName The name of the child
* @oaram nodeType the child type
* @return The created chid
* @throws Exception on unsuccessful child creation
*/
private FilePlanComponent createComponent(UserModel user, String parentComponentId, String componentName, String componentType, String componentTitle) throws Exception
public UnfiledContainerChild createUnfiledContainerChild(UserModel user, String parentId, String childName, String nodeType) throws Exception
{
FilePlanComponent filePlanComponentModel = createFilePlanComponentModel(componentName, componentType, componentTitle);
FilePlanComponent filePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI(user).createFilePlanComponent(filePlanComponentModel, parentComponentId);
UnfiledContainerChild childModel = createUnfiledContainerChildModel(childName, nodeType);
UnfiledContainerChild child = getRestAPIFactory().getUnfiledContainersAPI(user).createUnfiledContainerChild(childModel, parentId);
assertStatusCode(CREATED);
return filePlanComponent;
return child;
}
/**
* Helper method to create a child to an unfiled record container as the admin user
*
* @param parentId The id of the parent container
* @param childName The name of the child
* @oaram nodeType the child type
* @return The created chid
* @throws Exception on unsuccessful child creation
*/
public UnfiledContainerChild createUnfiledContainerChild(String parentId, String childName, String nodeType) throws Exception
{
return createUnfiledContainerChild(getAdminUser(), parentId, childName, nodeType);
}
/**
@@ -266,56 +367,55 @@ public class BaseRMRestTest extends RestTest
* @return The closed folder
* @throws Exception
*/
protected FilePlanComponent closeFolder(String folderId) throws Exception
protected RecordFolder closeFolder(String folderId) throws Exception
{
// build file plan component + properties for update request
FilePlanComponentProperties properties = new FilePlanComponentProperties();
properties.setIsClosed(true);
FilePlanComponent filePlanComponent = new FilePlanComponent();
filePlanComponent.setProperties(properties);
FilePlanComponent updatedComponent = getRestAPIFactory().getFilePlanComponentsAPI().updateFilePlanComponent(filePlanComponent, folderId);
RecordFolder recordFolderModel = RecordFolder.builder()
.properties(RecordFolderProperties.builder()
.isClosed(true)
.build())
.build();
RecordFolder updateRecordFolder = getRestAPIFactory().getRecordFolderAPI().updateRecordFolder(recordFolderModel, folderId);
assertStatusCode(OK);
return updatedComponent;
return updateRecordFolder;
}
/**
* Helper method to close record
* Helper method to complete record
*
* @param recordToClose Record to close
* @return The closed record
* @param recordId The id of the record to complete
* @return The completed record
* @throws Exception
*/
public FilePlanComponent closeRecord(FilePlanComponent recordToClose) throws Exception
public Record completeRecord(String recordId) throws Exception
{
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
List<String> aspects = filePlanComponentsAPI.getFilePlanComponent(recordToClose.getId()).getAspectNames();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
List<String> aspects = recordsAPI.getRecord(recordId).getAspectNames();
// this operation is only valid for records
assertTrue(aspects.contains(RECORD_TYPE));
// a record mustn't be closed
assertFalse(aspects.contains(ASPECTS_CLOSED_RECORD));
// a record mustn't be completed
assertFalse(aspects.contains(ASPECTS_COMPLETED_RECORD));
// add completed record aspect
aspects.add(ASPECTS_COMPLETED_RECORD);
// add closed record aspect
aspects.add(ASPECTS_CLOSED_RECORD);
FilePlanComponent updatedComponent = filePlanComponentsAPI.updateFilePlanComponent(FilePlanComponent.builder().aspectNames(aspects).build(),
recordToClose.getId());
Record updateRecord = recordsAPI.updateRecord(Record.builder().aspectNames(aspects).build(), recordId);
assertStatusCode(OK);
return updatedComponent;
return updateRecord;
}
/**
* Helper method to create a randomly-named <category>/<folder> structure in file plan
*
* @param user The user under whose privileges this structure is going to be created
* @param parentId parent container id
* @return record folder
* @return {@link RecordCategoryChild} which represents the record folder
* @throws Exception on failed creation
*/
public FilePlanComponent createCategoryFolderInFilePlan(UserModel user) throws Exception
public RecordCategoryChild createCategoryFolderInFilePlan(UserModel user) throws Exception
{
// create root category
FilePlanComponent recordCategory = createCategory(user, FILE_PLAN_ALIAS, "Category " + getRandomAlphanumeric());
RecordCategory recordCategory = createRootCategory(user, "Category " + getRandomAlphanumeric());
// and return a folder underneath
return createFolder(user, recordCategory.getId(), "Folder " + getRandomAlphanumeric());
@@ -324,38 +424,41 @@ public class BaseRMRestTest extends RestTest
/**
* Helper method to create a randomly-named <category>/<folder> structure in file plan as the admin user
*
* @param parentId parent container id
* @return record folder
* @return {@link RecordCategoryChild} which represents the record folder
* @throws Exception on failed creation
*/
public FilePlanComponent createCategoryFolderInFilePlan() throws Exception
public RecordCategoryChild createCategoryFolderInFilePlan() throws Exception
{
return createCategoryFolderInFilePlan(getAdminUser());
}
/**
* Helper method to retrieve a file plan component with user's privilege
*
* @param user user under whose privileges a component is to be read
* @param componentId id of the component to read
* @return {@link FilePlanComponent} for given componentId
* @throws Exception if user doesn't have sufficient privileges
*/
public FilePlanComponent getFilePlanComponentAsUser(UserModel user, String componentId) throws Exception
public UnfiledContainer getUnfiledContainerAsUser(UserModel user, String componentId) throws Exception
{
return getRestAPIFactory().getFilePlanComponentsAPI(user).getFilePlanComponent(componentId);
return getRestAPIFactory().getUnfiledContainersAPI(user).getUnfiledContainer(componentId);
}
/**
* Helper method to retrieve a file plan component with user's privilege as the admin user
*
* @param componentId id of the component to read
* @return {@link FilePlanComponent} for given componentId
* @throws Exception if user doesn't have sufficient privileges
*/
public FilePlanComponent getFilePlanComponent(String componentId) throws Exception
public UnfiledContainer getUnfiledContainer(String componentId) throws Exception
{
return getFilePlanComponentAsUser(getAdminUser(), componentId);
return getUnfiledContainerAsUser(getAdminUser(), componentId);
}
public TransferContainer getTransferContainerAsUser(UserModel user, String componentId) throws Exception
{
return getRestAPIFactory().getTransferContainerAPI(user).getTransferContainer(componentId);
}
public TransferContainer getTransferContainer(String componentId) throws Exception
{
return getTransferContainerAsUser(getAdminUser(), componentId);
}
public FilePlan getFilePlanAsUser(UserModel user, String componentId) throws Exception
{
return getRestAPIFactory().getFilePlansAPI(user).getFilePlan(componentId);
}
public FilePlan getFilePlan(String componentId) throws Exception
{
return getFilePlanAsUser(getAdminUser(), componentId);
}
}

View File

@@ -27,14 +27,11 @@
package org.alfresco.rest.rm.community.base;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.HOLDS_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.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.FILE_PLAN_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.HOLD_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.HOLD_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.TRANSFER_CONTAINER_TYPE;
@@ -74,12 +71,11 @@ public interface TestData
* @return file plan component alias
*/
@DataProvider
public static Object[][] getContainers()
public static String[][] getContainers()
{
return new Object[][] {
return new String[][] {
{ FILE_PLAN_ALIAS },
{ TRANSFERS_ALIAS },
{ HOLDS_ALIAS },
{ UNFILED_RECORDS_CONTAINER_ALIAS },
};
}
@@ -91,43 +87,42 @@ public interface TestData
* @return file plan component alias
*/
@DataProvider
public static Object[][] getContainersAndTypes()
public static String[][] getContainersAndTypes()
{
return new Object[][] {
return new String[][] {
{ FILE_PLAN_ALIAS, FILE_PLAN_TYPE },
{ TRANSFERS_ALIAS, TRANSFER_CONTAINER_TYPE },
{ HOLDS_ALIAS, HOLD_CONTAINER_TYPE },
{ UNFILED_RECORDS_CONTAINER_ALIAS, UNFILED_CONTAINER_TYPE },
};
}
/**
* The default CATEGORY name used when creating categories
* The default record category name used when creating categories
*/
public static String CATEGORY_NAME = "CATEGORY NAME" + getRandomAlphanumeric();
public static String RECORD_CATEGORY_NAME = "CATEGORY NAME" + getRandomAlphanumeric();
/**
* The default CATEGORY title used when creating categories
* The default record category title used when creating categories
*/
public static String CATEGORY_TITLE = "CATEGORY TITLE" + getRandomAlphanumeric();
public static String RECORD_CATEGORY_TITLE = "CATEGORY TITLE" + getRandomAlphanumeric();
/**
* The default FOLDER name used when creating folders
* The default record folder name used when creating folders
*/
public static String FOLDER_NAME = "FOLDER NAME" + getRandomAlphanumeric();
public static String RECORD_FOLDER_NAME = "FOLDER NAME" + getRandomAlphanumeric();
/**
* The default FOLDER title used when creating folders
* The default record folder title used when creating folders
*/
public static String FOLDER_TITLE = "FOLDER TITLE" + getRandomAlphanumeric();
public static String RECORD_FOLDER_TITLE = "FOLDER TITLE" + getRandomAlphanumeric();
/**
* The default electronic record name used when creating electronic records
* The default electronic record name used when creating electronic records
*/
public static String ELECTRONIC_RECORD_NAME = "Record electronic" + getRandomAlphanumeric();
/**
* The default Non electronic record name used when creating non-electronic records
* The default non-electronic record name used when creating non-electronic records
*/
public static String NONELECTRONIC_RECORD_NAME = "Record nonelectronic" + getRandomAlphanumeric();
@@ -138,22 +133,18 @@ public interface TestData
* @return file plan component alias
*/
@DataProvider
public static Object[][] childrenNotAllowedForCategory()
public static String[][] childrenNotAllowedForCategory()
{
return new Object[][] {
return new String[][] {
{ FILE_PLAN_TYPE },
{ TRANSFER_CONTAINER_TYPE },
{ HOLD_CONTAINER_TYPE },
{ UNFILED_CONTAINER_TYPE },
{ UNFILED_RECORD_FOLDER_TYPE },
{ HOLD_TYPE },
{ TRANSFER_TYPE },
{ CONTENT_TYPE }
};
}
/**
* Data Provider with:
* with the object types for creating a Record Folder
@@ -161,9 +152,9 @@ public interface TestData
* @return file plan component alias
*/
@DataProvider
public static Object[][] folderTypes()
public static String[][] folderTypes()
{
return new Object[][] {
return new String[][] {
{ RECORD_FOLDER_TYPE },
{ FOLDER_TYPE }
};
@@ -176,9 +167,9 @@ public interface TestData
* @return file plan component alias
*/
@DataProvider
public static Object[][] categoryTypes()
public static String[][] categoryTypes()
{
return new Object[][] {
return new String[][] {
{ FOLDER_TYPE },
{ RECORD_CATEGORY_TYPE }
};

View File

@@ -27,9 +27,19 @@
package org.alfresco.rest.rm.community.fileplancomponents;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.NON_ELECTRONIC_RECORD_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE;
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.UserRoles.ROLE_RM_POWER_USER;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicUnfiledContainerChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicUnfiledContainerChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile;
import static org.alfresco.utility.constants.UserRole.SiteCollaborator;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
@@ -37,22 +47,21 @@ import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordsAPI;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.RandomData;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.Test;
/**
* Create/File electronic records tests
* <br>
* These tests only test the creation and filing of electronic records, update at
* present isn't implemented in the API under test.
* <p>
* Delete records tests
*
* @author Kristijan Conkas
* @since 2.6
*/
@@ -60,15 +69,12 @@ public class DeleteRecordTests extends BaseRMRestTest
{
/**
* <pre>
* Given a record
* Given an electronic record
* And that I have the "Delete Record" capability
* And write permissions
* When I delete the record
* Then it is deleted from the file plan
* </pre>
*
* @param container
* @throws Exception
*/
@Test
(
@@ -76,26 +82,43 @@ public class DeleteRecordTests extends BaseRMRestTest
description = "Admin user can delete an electronic record"
)
@AlfrescoTest(jira="RM-4363")
public void adminCanDeleteElectronicRecord(FilePlanComponent container) throws Exception
public void adminCanDeleteElectronicRecord(String folderId, String type) throws Exception
{
FilePlanComponent newRecord = getRestAPIFactory().getFilePlanComponentsAPI().createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, container.getId());
// Create record
String recordId;
if(RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
recordId = getRestAPIFactory().getRecordFolderAPI().createRecord(createElectronicRecordModel(), folderId, getFile(IMAGE_FILE)).getId();
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
recordId = getRestAPIFactory().getUnfiledContainersAPI().uploadRecord(createElectronicUnfiledContainerChildModel(), folderId, getFile(IMAGE_FILE)).getId();
}
else if(UNFILED_RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
recordId = getRestAPIFactory().getUnfiledRecordFoldersAPI().uploadRecord(createElectronicUnfiledContainerChildModel(), folderId, getFile(IMAGE_FILE)).getId();
}
else
{
throw new Exception("Unsuported type = " + type);
}
// Assert status
assertStatusCode(CREATED);
deleteAndVerify(newRecord);
// Delete record and verify successful deletion
deleteAndVerify(recordId);
}
/**
* <pre>
* Given a record
* Given a non-electronic record
* And that I have the "Delete Record" capability
* And write permissions
* When I delete the record
* Then it is deleted from the file plan
* </pre>
*
* @param container
* @throws Exception
*/
@Test
(
@@ -103,27 +126,43 @@ public class DeleteRecordTests extends BaseRMRestTest
description = "Admin user can delete a non-electronic record"
)
@AlfrescoTest(jira="RM-4363")
public void adminCanDeleteNonElectronicRecord(FilePlanComponent container) throws Exception
public void adminCanDeleteNonElectronicRecord(String folderId, String type) throws Exception
{
// create a non-electronic record
FilePlanComponent newRecord = getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(createNonElectronicRecordModel(), container.getId());
// Create record
String nonElectronicRecordId;
if(RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
nonElectronicRecordId = getRestAPIFactory().getRecordFolderAPI().createRecord(createNonElectronicRecordModel(), folderId).getId();
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
nonElectronicRecordId = getRestAPIFactory().getUnfiledContainersAPI().createUnfiledContainerChild(createNonElectronicUnfiledContainerChildModel(), folderId).getId();
}
else if(UNFILED_RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
nonElectronicRecordId = getRestAPIFactory().getUnfiledRecordFoldersAPI().createUnfiledRecordFolderChild(createNonElectronicUnfiledContainerChildModel(), folderId).getId();
}
else
{
throw new Exception("Unsuported type = " + type);
}
// Assert status
assertStatusCode(CREATED);
deleteAndVerify(newRecord);
// Delete record and verify successful deletion
deleteAndVerify(nonElectronicRecordId);
}
/**
* <pre>
* Given a record
* Given a non-electronic record
* And that I don't have write permissions
* When I try to delete the record
* Then nothing happens
* And error gets reported
* </pre>
*
* @param container
* @throws Exception
*/
@Test
(
@@ -132,23 +171,27 @@ public class DeleteRecordTests extends BaseRMRestTest
@AlfrescoTest(jira="RM-4363")
public void userWithoutWritePermissionsCantDeleteRecord() throws Exception
{
// create a non-electronic record in unfiled records
FilePlanComponent newRecord = getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(createNonElectronicRecordModel(), UNFILED_RECORDS_CONTAINER_ALIAS);
// Create a non-electronic record in unfiled records
UnfiledContainerChild nonElectronicRecord = UnfiledContainerChild.builder()
.name("Record " + RandomData.getRandomAlphanumeric())
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
UnfiledContainerChild newRecord = getRestAPIFactory().getUnfiledContainersAPI().createUnfiledContainerChild(nonElectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
assertStatusCode(CREATED);
// create test user and add it with collab. privileges
// Create test user and add it with collaboration privileges
UserModel deleteUser = getDataUser().createRandomTestUser("delnoperm");
deleteUser.setUserRole(UserRole.SiteCollaborator);
logger.info("test user: " + deleteUser.getUsername());
getDataUser().addUserToSite(deleteUser, new SiteModel(getRestAPIFactory().getRMSiteAPI().getSite().getId()), UserRole.SiteCollaborator);
String username = deleteUser.getUsername();
logger.info("Test user: " + username);
getDataUser().addUserToSite(deleteUser, new SiteModel(getRestAPIFactory().getRMSiteAPI().getSite().getId()), SiteCollaborator);
// add RM role to user
getRestAPIFactory().getRMUserAPI().assignRoleToUser(deleteUser.getUsername(), UserRoles.ROLE_RM_POWER_USER);
// Add RM role to user
getRestAPIFactory().getRMUserAPI().assignRoleToUser(username, ROLE_RM_POWER_USER);
assertStatusCode(OK);
// try to delete newRecord
getRestAPIFactory().getFilePlanComponentsAPI(deleteUser).deleteFilePlanComponent(newRecord.getId());
// Try to delete newRecord
getRestAPIFactory().getRecordsAPI(deleteUser).deleteRecord(newRecord.getId());
assertStatusCode(FORBIDDEN);
}
@@ -160,9 +203,6 @@ public class DeleteRecordTests extends BaseRMRestTest
* Then nothing happens
* And error gets reported
* </pre>
*
* @param container
* @throws Exception
*/
@Test
(
@@ -171,56 +211,55 @@ public class DeleteRecordTests extends BaseRMRestTest
@AlfrescoTest(jira="RM-4363")
public void userWithoutDeleteRecordsCapabilityCantDeleteRecord() throws Exception
{
// create test user and add it with collab. privileges
// Create test user and add it with collaboration privileges
UserModel deleteUser = getDataUser().createRandomTestUser("delnoperm");
deleteUser.setUserRole(UserRole.SiteCollaborator);
getDataUser().addUserToSite(deleteUser, new SiteModel(getRestAPIFactory().getRMSiteAPI().getSite().getId()), UserRole.SiteCollaborator);
logger.info("test user: " + deleteUser.getUsername());
getDataUser().addUserToSite(deleteUser, new SiteModel(getRestAPIFactory().getRMSiteAPI().getSite().getId()), SiteCollaborator);
String username = deleteUser.getUsername();
logger.info("Test user: " + username);
// add RM role to user, RM Power User doesn't have the Delete Record capabilities
getRestAPIFactory().getRMUserAPI().assignRoleToUser(deleteUser.getUsername(), UserRoles.ROLE_RM_POWER_USER);
// Add RM role to user, RM Power User doesn't have the "Delete Record" capabilities
getRestAPIFactory().getRMUserAPI().assignRoleToUser(username, ROLE_RM_POWER_USER);
assertStatusCode(OK);
// create random folder
FilePlanComponent randomFolder = createCategoryFolderInFilePlan();
logger.info("random folder:" + randomFolder.getName());
// Create random folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
logger.info("Random folder:" + recordFolder.getName());
// grant deleteUser Filing privileges on randomFolder category, this will be
// inherited to randomFolder
FilePlanComponentAPI filePlanComponentsAPIAsAdmin = getRestAPIFactory().getFilePlanComponentsAPI();
getRestAPIFactory().getRMUserAPI().addUserPermission(filePlanComponentsAPIAsAdmin.getFilePlanComponent(randomFolder.getParentId()),
deleteUser, UserPermissions.PERMISSION_FILING);
// Grant "deleteUser" filing permissions on "randomFolder" parent, this will be inherited to randomFolder
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
getRestAPIFactory().getRMUserAPI().addUserPermission(recordCategoryAPI.getRecordCategory(recordFolder.getParentId()).getId(), deleteUser, PERMISSION_FILING);
assertStatusCode(OK);
// create a non-electronic record in randomFolder
FilePlanComponent newRecord = filePlanComponentsAPIAsAdmin.createFilePlanComponent(createNonElectronicRecordModel(), randomFolder.getId());
// Create a non-electronic record in "randomFolder"
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
Record newRecord = recordFolderAPI.createRecord(createNonElectronicRecordModel(), recordFolder.getId());
assertStatusCode(CREATED);
// verify the user can see the newRecord
FilePlanComponentAPI filePlanComponentsAPIAsUser = getRestAPIFactory().getFilePlanComponentsAPI(deleteUser);
filePlanComponentsAPIAsUser.getFilePlanComponent(newRecord.getId());
// Verify the user can see "newRecord"
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI(deleteUser);
recordsAPI.getRecord(newRecord.getId());
assertStatusCode(OK);
// try to delete newRecord
filePlanComponentsAPIAsUser.deleteFilePlanComponent(newRecord.getId());
// Try to delete "newRecord"
recordsAPI.deleteRecord(newRecord.getId());
assertStatusCode(FORBIDDEN);
}
/**
* Utility method to delete a record and verify successful deletion
* @param record
* @throws Exception
*
* @param recordId The id of the record
*/
private void deleteAndVerify(FilePlanComponent record) throws Exception
private void deleteAndVerify(String recordId)
{
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// delete it and verify status
filePlanComponentsAPI.deleteFilePlanComponent(record.getId());
// Delete record and verify status
recordsAPI.deleteRecord(recordId);
assertStatusCode(NO_CONTENT);
// try to get deleted file plan component
filePlanComponentsAPI.getFilePlanComponent(record.getId());
// Try to get deleted record
recordsAPI.deleteRecord(recordId);
assertStatusCode(NOT_FOUND);
}
}

View File

@@ -26,18 +26,20 @@
*/
package org.alfresco.rest.rm.community.fileplancomponents;
import static org.alfresco.rest.rm.community.base.TestData.CATEGORY_NAME;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.base.TestData.FOLDER_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.HOLDS_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.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicUnfiledContainerChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createTempFile;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
@@ -46,40 +48,40 @@ import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentContent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
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.utility.report.Bug;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Create/File electronic records tests
* <br>
* These tests only test the creation and filing of electronic records, update at
* present isn't implemented in the API under test.
* <p>
*
* @author Kristijan Conkas
* @since 2.6
*/
public class ElectronicRecordTests extends BaseRMRestTest
{
/** Valid root containers where electronic records can be created */
private static final String TEXT_PLAIN_VALUE = "text/plain";
/** Invalid parent containers where electronic records can't be created */
@DataProvider(name = "invalidParentContainers")
public Object[][] invalidContainers() throws Exception
public String[][] invalidParentContainers() throws Exception
{
return new Object[][]
return new String[][]
{
// record category
{ getFilePlanComponent(createCategoryFolderInFilePlan().getParentId()) },
{ createCategoryFolderInFilePlan().getParentId() },
// file plan root
{ getFilePlanComponent(FILE_PLAN_ALIAS) },
{ FILE_PLAN_ALIAS },
// transfers
{ getFilePlanComponent(TRANSFERS_ALIAS) },
// holds
{ getFilePlanComponent(HOLDS_ALIAS) },
{ TRANSFERS_ALIAS }
};
}
@@ -90,21 +92,21 @@ public class ElectronicRecordTests extends BaseRMRestTest
* Then nothing happens
* And an error is reported
* </pre>
* @param container
* @throws Exception
* @param container The parent container
* @throws Exception if record can't be created
*/
@Test
(
dataProvider = "invalidParentContainers",
description = "Electronic records can't be created in invalid parent containers"
)
public void cantCreateElectronicRecordsInInvalidContainers(FilePlanComponent container) throws Exception
public void cantCreateElectronicRecordsInInvalidContainers(String container) throws Exception
{
// Build object the filePlan, this should throw an IllegalArgumentException
getRestAPIFactory().getFilePlanComponentsAPI().createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, container.getId());
// Create an electronic record in the given container, this should throw an IllegalArgumentException
getRestAPIFactory().getRecordFolderAPI().createRecord(createElectronicRecordModel(), container, getFile(IMAGE_FILE));
// verify the create request status code
assertStatusCode(UNPROCESSABLE_ENTITY);
// Verify the create request status code
assertStatusCode(BAD_REQUEST);
}
/**
@@ -115,7 +117,7 @@ public class ElectronicRecordTests extends BaseRMRestTest
* Then nothing happens
* And an error is reported
* </pre>
* @throws Exception
* @throws Exception if record can't be created
*/
@Test
(
@@ -123,18 +125,18 @@ public class ElectronicRecordTests extends BaseRMRestTest
)
public void cantCreateElectronicRecordInClosedFolder() throws Exception
{
FilePlanComponent recordFolder = createCategoryFolderInFilePlan();
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
// the folder should be open
// The folder should be open
assertFalse(recordFolder.getProperties().getIsClosed());
// close the folder
// Close the folder
closeFolder(recordFolder.getId());
// try to create it, this should throw IllegalArgumentException
getRestAPIFactory().getFilePlanComponentsAPI().createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, recordFolder.getId());
// Try to create an electronic record, this should throw IllegalArgumentException
getRestAPIFactory().getRecordFolderAPI().createRecord(createElectronicRecordModel(), recordFolder.getId(), getFile(IMAGE_FILE));
// verify the status code
// Verify the status code
assertStatusCode(UNPROCESSABLE_ENTITY);
}
@@ -149,39 +151,57 @@ public class ElectronicRecordTests extends BaseRMRestTest
* </pre>
* and
* <pre>
*
*
* Given a parent container that is an unfiled record folder or the root unfiled record container
* When I try to create an electronic record within the parent container
* And I do not provide all the required mandatory property values
* Then nothing happens
* And an error is reported
* </pre>
* @param container
* @throws Exception
* @param folderid The folder, which the record will be created in
* @param type The type of the record folder, which the record will be created in
* @throws Exception if record can't be created
*/
@Test
(
dataProvider = "validRootContainers",
description = "Electronic record can only be created if all mandatory properties are given"
)
public void canCreateElectronicRecordOnlyWithMandatoryProperties(FilePlanComponent container) throws Exception
public void canCreateElectronicRecordOnlyWithMandatoryProperties(String folderId, String type) throws Exception
{
logger.info("Root container:\n" + toJson(container));
logger.info("Root container:\n" + toJson(folderId));
if (container.getNodeType().equals(RECORD_FOLDER_TYPE))
if (RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
// only record folders can be open or closed
assertFalse(container.getProperties().getIsClosed());
// Only record folders can be opened or closed
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolder(folderId).getProperties().getIsClosed());
// Record without name
Record recordModel = Record.builder().nodeType(CONTENT_TYPE).build();
// Try to create it
recordFolderAPI.createRecord(recordModel, folderId);
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordModel = UnfiledContainerChild.builder().nodeType(CONTENT_TYPE).build();
unfiledContainersAPI.createUnfiledContainerChild(recordModel, folderId);
}
else if(UNFILED_RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild recordModel = UnfiledContainerChild.builder().nodeType(CONTENT_TYPE).build();
unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(recordModel, folderId);
}
else
{
throw new Exception("Unsuported type = " + type);
}
// component without name
FilePlanComponent record = FilePlanComponent.builder()
.nodeType(CONTENT_TYPE)
.build();
// try to create it
getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(record, container.getId());
// verify the status code is BAD_REQUEST
// Verify the status code is BAD_REQUEST
assertStatusCode(BAD_REQUEST);
}
@@ -195,151 +215,185 @@ public class ElectronicRecordTests extends BaseRMRestTest
* </pre>
* and
* <pre>
*
* Given a parent container that is an unfiled record folder or the root unfiled record container
* When I try to create an electronic record within the parent container
* Then the electronic record is created
* And the details of the new record are returned
* </pre>
* @throws Exception
* @param folderId The folder, which the record will be created in
* @param type The type of the folder, which the record will be created in
* @throws Exception if record can't be created
*/
@Test
(
dataProvider = "validRootContainers",
description = "Electronic records can be created in unfiled record folder or unfiled record root"
description = "Electronic records can be created in record folders, unfiled record folders or unfiled record folder root"
)
public void canCreateElectronicRecordsInValidContainers(FilePlanComponent container) throws Exception
public void canCreateElectronicRecordsInValidContainers(String folderId, String type) throws Exception
{
FilePlanComponent record = createElectronicRecordModel();
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
String newRecordId = filePlanComponentsAPI.createElectronicRecord(record, IMAGE_FILE, container.getId()).getId();
// verify the create request status code
String newRecordId;
String expectedName;
if (RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
Record recordModel = createElectronicRecordModel();
newRecordId = recordFolderAPI.createRecord(recordModel, folderId, getFile(IMAGE_FILE)).getId();
expectedName = recordModel.getName();
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordModel = createElectronicUnfiledContainerChildModel();
newRecordId = unfiledContainersAPI.uploadRecord(recordModel, folderId, getFile(IMAGE_FILE)).getId();
expectedName = recordModel.getName();
}
else if(UNFILED_RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild recordModel = createElectronicUnfiledContainerChildModel();
newRecordId = unfiledRecordFoldersAPI.uploadRecord(recordModel, folderId, getFile(IMAGE_FILE)).getId();
expectedName = recordModel.getName();
}
else
{
throw new Exception("Unsuported type = " + type);
}
// Verify the create request status code
assertStatusCode(CREATED);
// get newly created electronic record and verify its properties
FilePlanComponent electronicRecord = filePlanComponentsAPI.getFilePlanComponent(newRecordId);
// created record will have record identifier inserted in its name but will be prefixed with
// the name it was created as
assertTrue(electronicRecord.getName().startsWith(record.getName()));
assertTrue(electronicRecord.getName().contains(electronicRecord.getProperties().getRmIdentifier()));
// Get newly created electronic record and verify its properties
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
Record record = recordsAPI.getRecord(newRecordId);
String recordName = record.getName();
// Created record will have record identifier inserted in its name but will be prefixed with the name it was created as
assertTrue(recordName.startsWith(expectedName));
assertTrue(recordName.contains(record.getProperties().getIdentifier()));
}
/**
* This test verified that in the test client implementation if record name isn't specified it
* defaults to filed file name.
* @param container valid record container
* @throws Exception if record creation failed
* <pre>
* Given that a record name isn't specified
* When I create an electronic record
* Then the record name defaults to filed file name.
* </pre>
* @param folderId The folder, which the record will be created in
* @param type The type of the folder, which the record will be created in
* @throws Exception if record can't be created
*/
@Test
(
dataProvider = "validRootContainers",
description = "Electronic records can be created in unfiled record folder or unfiled record root"
)
public void recordNameDerivedFromFileName(FilePlanComponent container) throws Exception
public void recordNameDerivedFromFileName(String folderId, String type) throws Exception
{
// record object without name set
FilePlanComponent record = FilePlanComponent.builder()
.nodeType(CONTENT_TYPE)
.build();
String newRecordId;
if (RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
// Create a record model without a name
Record recordModel = Record.builder().nodeType(CONTENT_TYPE).build();
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
String newRecordId = filePlanComponentsAPI.createElectronicRecord(record, IMAGE_FILE, container.getId()).getId();
// verify the create request status code
// Create an electronic record
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
newRecordId = recordFolderAPI.createRecord(recordModel, folderId, getFile(IMAGE_FILE)).getId();
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild recordModel = UnfiledContainerChild.builder().nodeType(CONTENT_TYPE).build();
newRecordId = unfiledContainersAPI.uploadRecord(recordModel, folderId, getFile(IMAGE_FILE)).getId();
}
else if(UNFILED_RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild recordModel = UnfiledContainerChild.builder().nodeType(CONTENT_TYPE).build();
newRecordId = unfiledRecordFoldersAPI.uploadRecord(recordModel, folderId, getFile(IMAGE_FILE)).getId();
}
else
{
throw new Exception("Unsuported type = " + type);
}
// Verify the create request status code
assertStatusCode(CREATED);
// get newly created electonic record and verify its properties
FilePlanComponent electronicRecord = filePlanComponentsAPI.getFilePlanComponent(newRecordId);
// record will have record identifier inserted in its name but will for sure start with file name
// and end with its extension
// Get newly created electronic record and verify its properties
Record electronicRecord = getRestAPIFactory().getRecordsAPI().getRecord(newRecordId);
// Record will have record identifier inserted in its name but will for sure start with file name and end with its extension
assertTrue(electronicRecord.getName().startsWith(IMAGE_FILE.substring(0, IMAGE_FILE.indexOf("."))));
assertTrue(electronicRecord.getName().contains(electronicRecord.getProperties().getRmIdentifier()));
assertTrue(electronicRecord.getName().contains(electronicRecord.getProperties().getIdentifier()));
}
@Test
@Bug (id = "RM-4568")
/**
* Given I want to create an electronic record
* When I use the path relative to the filePlanComponentid
* <pre>
* Given that I want to create an electronic record in one unfiled record folder
* When I use the path relative to the one unfiled record folder
* Then the containers in the relativePath that don't exist are created before creating the electronic record
* <pre>
*/
public void createElectronicRecordWithRelativePath() throws Exception
{
//the containers specified on the RELATIVE_PATH parameter don't exist on server
String RELATIVE_PATH = CATEGORY_NAME + "/" + CATEGORY_NAME + "/" + FOLDER_NAME;
FilePlanComponent electronicRecord = FilePlanComponent.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE.toString())
.content(FilePlanComponentContent
.builder()
.mimeType("text/plain")
.build()
)
.properties(FilePlanComponentProperties
.builder()
.description(ELECTRONIC_RECORD_NAME)
.build()
)
.relativePath(RELATIVE_PATH)
.build();
// The containers specified on the relativePath parameter don't exist on server
String parentUbnfiledRecordFolderName = "ParentUnfiledRecordFolder" + getRandomAlphanumeric();
String unfiledRecordFolderPathEl1 = "UnfiledRecordFolderPathEl1" + getRandomAlphanumeric();
String unfiledRecordFolderPathEl2 = "UnfiledRecordFolderPathEl2" + getRandomAlphanumeric();
String unfiledRecordFolderPathEl3 = "UnfiledRecordFolderPathEl3" + getRandomAlphanumeric();
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent recordCreated = filePlanComponentsAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), FILE_PLAN_ALIAS);
String parentUnfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, parentUbnfiledRecordFolderName, UNFILED_RECORD_FOLDER_TYPE).getId();
String relativePath = unfiledRecordFolderPathEl1 + "/" + unfiledRecordFolderPathEl2 + "/" + unfiledRecordFolderPathEl3;
UnfiledContainerChild unfiledContainerChildModel= UnfiledContainerChild.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder()
.mimeType(TEXT_PLAIN_VALUE)
.build())
.relativePath(relativePath)
.build();
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild recordCreated = unfiledRecordFoldersAPI.uploadRecord(unfiledContainerChildModel, parentUnfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
// Verify the create request status code
assertStatusCode(CREATED);
// Get newly created electronic record and verify its properties
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
Record record = recordsAPI.getRecord(recordCreated.getId());
assertTrue(record.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolder(record.getParentId()).getName().equals(unfiledRecordFolderPathEl3));
// The first relative path element exists and the second one does not exist
String unfiledRecordFolderPathEl4 = "UnfiledRecordFolderPathEl4" + getRandomAlphanumeric();
relativePath = unfiledRecordFolderPathEl1 + "/" + unfiledRecordFolderPathEl4;
unfiledContainerChildModel.setRelativePath(relativePath);
recordCreated = unfiledRecordFoldersAPI.uploadRecord(unfiledContainerChildModel, parentUnfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
// verify the create request status code
assertStatusCode(CREATED);
// get newly created electronic record and verify its properties
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getId())
.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getId())
.getProperties().getDescription().equals(ELECTRONIC_RECORD_NAME));
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getParentId())
.getName().equals(FOLDER_NAME));
//get newly created electronic record using the relativePath
assertTrue(filePlanComponentsAPI.getFilePlanComponent(FILE_PLAN_ALIAS, FilePlanComponentFields.RELATIVE_PATH + "=" + RELATIVE_PATH + "/" + recordCreated.getName())
.getId().equals(recordCreated.getId()));
record = recordsAPI.getRecord(recordCreated.getId());
//the category specified via the RELATIVE_PATH exist, folder doesn't exist
RELATIVE_PATH = CATEGORY_NAME + "/" + FOLDER_NAME;
electronicRecord.setRelativePath(RELATIVE_PATH);
recordCreated = filePlanComponentsAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), FILE_PLAN_ALIAS);
// verify the create request status code
assertStatusCode(CREATED);
// get newly created electronic record and verify its properties
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getId())
.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getParentId())
.getName().startsWith(FOLDER_NAME));
//get newly created electronic record using the relativePath
assertTrue(filePlanComponentsAPI.getFilePlanComponent(FILE_PLAN_ALIAS, FilePlanComponentFields.RELATIVE_PATH + "=" + RELATIVE_PATH + "/" + recordCreated.getName())
.getId().equals(recordCreated.getId()));
assertTrue(record.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolder(record.getParentId()).getName().equals(unfiledRecordFolderPathEl4));
//the containers from the RELATIVE PATH exists
electronicRecord.setName(ELECTRONIC_RECORD_NAME + getRandomAlphanumeric());
recordCreated = filePlanComponentsAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), FILE_PLAN_ALIAS);
unfiledContainerChildModel.setName(ELECTRONIC_RECORD_NAME + getRandomAlphanumeric());
recordCreated = unfiledRecordFoldersAPI.uploadRecord(unfiledContainerChildModel, parentUnfiledRecordFolderId, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME));
// verify the create request status code
assertStatusCode(CREATED);
// get newly created electronic record and verify its properties
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getId())
.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getParentId())
.getName().startsWith(FOLDER_NAME));
//get newly created electronic record using the relativePath
assertTrue(filePlanComponentsAPI.getFilePlanComponent(FILE_PLAN_ALIAS, FilePlanComponentFields.RELATIVE_PATH + "=" + RELATIVE_PATH + "/" + recordCreated.getName())
.getId().equals(recordCreated.getId()));
record = recordsAPI.getRecord(recordCreated.getId());
//create the container structure relative to the categoryId
String categoryId = filePlanComponentsAPI.getFilePlanComponent(FILE_PLAN_ALIAS, FilePlanComponentFields.RELATIVE_PATH + "=" + CATEGORY_NAME)
.getId();
RELATIVE_PATH = CATEGORY_NAME + CATEGORY_NAME + "/" + FOLDER_NAME;
electronicRecord.setRelativePath(RELATIVE_PATH);
recordCreated = filePlanComponentsAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), categoryId);
// verify the create request status code
assertStatusCode(CREATED);
// get newly created electronic record and verify its properties
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getId())
.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(filePlanComponentsAPI.getFilePlanComponent(recordCreated.getParentId())
.getName().startsWith(FOLDER_NAME));
assertTrue(record.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(unfiledRecordFoldersAPI.getUnfiledRecordFolder(record.getParentId()).getName().equals(unfiledRecordFolderPathEl4));
}
}

View File

@@ -27,35 +27,30 @@
package org.alfresco.rest.rm.community.fileplancomponents;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.base.AllowableOperations.CREATE;
import static org.alfresco.rest.rm.community.base.AllowableOperations.DELETE;
import static org.alfresco.rest.rm.community.base.AllowableOperations.UPDATE;
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.FilePlanComponentFields.ALLOWABLE_OPERATIONS;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.TestData;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RMSiteAPI;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.transfercontainer.TransferContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.utility.model.UserModel;
import org.alfresco.utility.report.Bug;
import org.testng.annotations.Test;
/**
* This class contains the tests for
* the File Plan CRUD API
* This class contains the tests for the File Plan CRUD API
*
* @author Rodica Sutu
* @since 2.6
@@ -63,17 +58,19 @@ import org.testng.annotations.Test;
public class FilePlanTests extends BaseRMRestTest
{
/**
* <pre>
* Given that the RM site doesn't exist
* When I use the API to get the File Plan/Holds/Unfiled Records Container/Transfers
* Then I get the 404 response code
* </pre>
*/
@Test
(
description = "Check the GET response code when the RM site doesn't exist",
description = "Check the GET response for the special contianers when the RM site doesn't exist",
dataProviderClass = TestData.class,
dataProvider = "getContainers"
)
public void getFilePlanComponentWhenRMIsNotCreated(String filePlanComponentAlias) throws Exception
public void getContainersWhenRMIsNotCreated(String containerAlias) throws Exception
{
RMSiteAPI rmSiteAPI = getRestAPIFactory().getRMSiteAPI();
@@ -84,217 +81,156 @@ public class FilePlanTests extends BaseRMRestTest
rmSiteAPI.deleteRMSite();
}
// Get the file plan component
getRestAPIFactory().getFilePlanComponentsAPI().getFilePlanComponent(filePlanComponentAlias);
if (FILE_PLAN_ALIAS.equalsIgnoreCase(containerAlias))
{
getRestAPIFactory().getFilePlansAPI().getFilePlan(containerAlias);
}
else if(TRANSFERS_ALIAS.equalsIgnoreCase(containerAlias))
{
getRestAPIFactory().getTransferContainerAPI().getTransferContainer(containerAlias);
}
else
{
getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(containerAlias);
}
//check the response code is NOT_FOUND
// Check the response code is NOT_FOUND
assertStatusCode(NOT_FOUND);
}
/**
* <pre>
* Given that a file plan exists
* When I ask the API for the details of the file plan
* Then I am given the details of the file plan
* </pre>
*/
@Test
(
description = "Check the GET response for special file plan components when the RM site exit",
description = "Check the GET response for the special containers when the RM site exit",
dataProviderClass = TestData.class,
dataProvider = "getContainersAndTypes"
)
public void getFilePlanComponentWhenRMIsCreated(String filePlanComponentAlias, String filePlanComponentType) throws Exception
public void getContainersWhenRMIsCreated(String containerAlias, String containerType) throws Exception
{
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
// Get the file plan special container
FilePlanComponent filePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI().getFilePlanComponent(filePlanComponentAlias);
FilePlan filePlan = null;
TransferContainer transferContainer = null;
UnfiledContainer unfiledContainer = null;
if (FILE_PLAN_ALIAS.equalsIgnoreCase(containerAlias))
{
filePlan = getRestAPIFactory().getFilePlansAPI().getFilePlan(containerAlias);
}
else if(TRANSFERS_ALIAS.equalsIgnoreCase(containerAlias))
{
transferContainer = getRestAPIFactory().getTransferContainerAPI().getTransferContainer(containerAlias);
}
else
{
unfiledContainer = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(containerAlias);
}
// Check the response code
assertStatusCode(OK);
// Check the response contains the right node type
assertEquals(filePlanComponent.getNodeType(), filePlanComponentType);
if (FILE_PLAN_ALIAS.equalsIgnoreCase(containerAlias))
{
assertEquals(filePlan.getNodeType(), containerType);
}
else if(TRANSFERS_ALIAS.equalsIgnoreCase(containerAlias))
{
assertEquals(transferContainer.getNodeType(), containerType);
}
else
{
assertEquals(unfiledContainer.getNodeType(), containerType);
}
}
/**
* <pre>
* Given that a file plan exists
* When I ask the API for the details of the file plan to include the allowableOperations property
* Then I am given the allowableOperations property with the update and create operations.
* </pre>
*/
@Test
(
description = "Check the allowableOperations list returned ",
description = "Check the allowableOperations list returned",
dataProviderClass = TestData.class,
dataProvider = "getContainers"
)
public void includeAllowableOperations(String specialContainerAlias) throws Exception
public void includeAllowableOperations(String containerAlias) throws Exception
{
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
// Get the file plan special containers with the optional parameter allowableOperations
FilePlanComponent filePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI().getFilePlanComponent(specialContainerAlias, "include=" + ALLOWABLE_OPERATIONS);
FilePlan filePlan = null;
TransferContainer transferContainer = null;
UnfiledContainer unfiledContainer = null;
// Check the list of allowableOperations returned
if(specialContainerAlias.equals(TRANSFERS_ALIAS))
if (FILE_PLAN_ALIAS.equalsIgnoreCase(containerAlias))
{
assertTrue(filePlanComponent.getAllowableOperations().containsAll(asList(UPDATE)),
"Wrong list of the allowable operations is return" + filePlanComponent.getAllowableOperations().toString());
// Check the list of allowableOperations returned
filePlan = getRestAPIFactory().getFilePlansAPI().getFilePlan(containerAlias, "include=" + ALLOWABLE_OPERATIONS);
assertTrue(filePlan.getAllowableOperations().containsAll(asList(UPDATE, CREATE)),
"Wrong list of the allowable operations is return" + filePlan.getAllowableOperations().toString());
// Check the list of allowableOperations doesn't contain DELETE operation
assertFalse(filePlan.getAllowableOperations().contains(DELETE),
"The list of allowable operations contains delete option" + filePlan.getAllowableOperations().toString());
}
else if (TRANSFERS_ALIAS.equalsIgnoreCase(containerAlias))
{
// Check the list of allowableOperations returned
transferContainer = getRestAPIFactory().getTransferContainerAPI().getTransferContainer(containerAlias, "include=" + ALLOWABLE_OPERATIONS);
assertTrue(transferContainer.getAllowableOperations().containsAll(asList(UPDATE)),
"Wrong list of the allowable operations is return" + transferContainer.getAllowableOperations().toString());
// Check the list of allowableOperations doesn't contain DELETE operation
assertFalse(transferContainer.getAllowableOperations().contains(DELETE),
"The list of allowable operations contains delete option" + transferContainer.getAllowableOperations().toString());
// Check the list of allowableOperations doesn't contain DELETE operation
assertFalse(transferContainer.getAllowableOperations().contains(CREATE),
"The list of allowable operations contains delete option" + transferContainer.getAllowableOperations().toString());
}
else
{
assertTrue(filePlanComponent.getAllowableOperations().containsAll(asList(UPDATE, CREATE)),
"Wrong list of the allowable operations is return" + filePlanComponent.getAllowableOperations().toString());
unfiledContainer = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(containerAlias, "include=" + ALLOWABLE_OPERATIONS);
// Check the list of allowableOperations returned
assertTrue(unfiledContainer.getAllowableOperations().containsAll(asList(UPDATE, CREATE)),
"Wrong list of the allowable operations is return" + unfiledContainer.getAllowableOperations().toString());
// Check the list of allowableOperations doesn't contain DELETE operation
assertFalse(unfiledContainer.getAllowableOperations().contains(DELETE),
"The list of allowable operations contains delete option" + unfiledContainer.getAllowableOperations().toString());
}
// Check the list of allowableOperations doesn't contains DELETE operation
assertFalse(filePlanComponent.getAllowableOperations().contains(DELETE),
"The list of allowable operations contains delete option" + filePlanComponent.getAllowableOperations().toString());
}
/**
* Given that a file plan exists
* When I ask the API to modify the details of the file plan
* Then the details of the file are modified
* Note: the details of the file plan are limited to title and description.
*/
@Test
@Bug (id = "RM-4295")
public void updateFilePlan() throws Exception
{
String FILE_PLAN_DESCRIPTION = "Description updated " + getRandomAlphanumeric();
String FILE_PLAN_TITLE = "Title updated " + getRandomAlphanumeric();
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
// Build object for updating the filePlan
FilePlanComponent filePlanComponent = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.title(FILE_PLAN_TITLE)
.description(FILE_PLAN_DESCRIPTION)
.build())
.build();
// Update the record category
FilePlanComponent renamedFilePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI().updateFilePlanComponent(filePlanComponent, FILE_PLAN_ALIAS);
// Verify the response status code
assertStatusCode(OK);
// Verify the returned description field for the file plan component
assertEquals(renamedFilePlanComponent.getProperties().getDescription(), FILE_PLAN_DESCRIPTION);
// Verify the returned title field for the file plan component
assertEquals(renamedFilePlanComponent.getProperties().getTitle(), FILE_PLAN_TITLE);
}
/**
* Given that a file plan exists
* When I ask the API to delete the file plan
* Then the 422 response code is returned.
*/
@Test
(
description = "Check the response code when deleting the special file plan components",
dataProviderClass = TestData.class,
dataProvider = "getContainers"
)
public void deleteFilePlanSpecialComponents(String filePlanComponentAlias) throws Exception
{
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
// Delete the file plan component
getRestAPIFactory().getFilePlanComponentsAPI().deleteFilePlanComponent(filePlanComponentAlias);
// Check the DELETE response status code
assertStatusCode(UNPROCESSABLE_ENTITY);
}
/**
* Given that a file plan exists and I am a non RM user
* When I ask the API to delete the file plan
* Then the 403 response code is returned.
*/
@Test
(
description = "Check the response code when deleting the special file plan components with non RM user",
dataProviderClass = TestData.class,
dataProvider = "getContainers"
)
public void deleteFilePlanSpecialComponentsNonRMUser(String filePlanComponentAlias) throws Exception
{
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
// Create a random user
UserModel nonRMuser = getDataUser().createRandomTestUser("testUser");
// Delete the file plan component
getRestAPIFactory().getFilePlanComponentsAPI(nonRMuser).deleteFilePlanComponent(filePlanComponentAlias);
// Check the DELETE response status code
assertStatusCode(FORBIDDEN);
}
/**
* <pre>
* Given that RM site exists
* When I ask to create the file plan
* Then the 403 response code is returned.
*/
@Test
(
description = "Check the response code when creating the special file plan components",
dataProviderClass = TestData.class,
dataProvider = "getContainersAndTypes"
)
@Bug(id = "RM-4296")
public void createFilePlanSpecialContainerWhenExists(String filePlanComponentAlias, String filePlanComponentType) throws Exception
{
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
// Get the RM site ID
String rmSiteId = getRestAPIFactory().getRMSiteAPI().getSite().getGuid();
String name = filePlanComponentAlias + getRandomAlphanumeric();
// Build the file plan root properties
FilePlanComponent filePlanComponent = FilePlanComponent.builder()
.name(name)
.nodeType(filePlanComponentType)
.properties(FilePlanComponentProperties.builder()
.build())
.build();
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
// Create the special containers into RM site - parent folder
filePlanComponentsAPI.createFilePlanComponent(filePlanComponent, rmSiteId);
assertStatusCode(UNPROCESSABLE_ENTITY);
// Create the special containers into RM site - parent folder
filePlanComponentsAPI.createFilePlanComponent(filePlanComponent, FILE_PLAN_ALIAS);
assertStatusCode(UNPROCESSABLE_ENTITY);
// Create the special containers into the root of special containers containers
filePlanComponentsAPI.createFilePlanComponent(filePlanComponent, filePlanComponentAlias);
assertStatusCode(UNPROCESSABLE_ENTITY);
}
/**
* Given that RM site exists
* When a non-RM user ask the API for the details of the file plan
* When a non-RM user asks the API for the details of the file plan
* Then the status code 403 (Permission denied) is return
* </pre>
*/
@Test
(
description = "Check the response code when the RM site containers are get with non rm users",
description = "Check the response code when the RM site containers are get with non-RM users",
dataProviderClass = TestData.class,
dataProvider = "getContainers"
)
public void getSpecialFilePlanComponentsWithNonRMuser(String filePlanComponentAlias) throws Exception
public void getContainersWithNonRMuser(String containerAlias) throws Exception
{
// Create RM Site if doesn't exist
createRMSiteIfNotExists();
@@ -303,7 +239,18 @@ public class FilePlanTests extends BaseRMRestTest
UserModel nonRMuser = getDataUser().createRandomTestUser("testUser");
// Get the special file plan components
getRestAPIFactory().getFilePlanComponentsAPI(nonRMuser).getFilePlanComponent(filePlanComponentAlias);
if (FILE_PLAN_ALIAS.equalsIgnoreCase(containerAlias))
{
getRestAPIFactory().getFilePlansAPI(nonRMuser).getFilePlan(containerAlias);
}
else if(TRANSFERS_ALIAS.equalsIgnoreCase(containerAlias))
{
getRestAPIFactory().getTransferContainerAPI(nonRMuser).getTransferContainer(containerAlias);
}
else
{
getRestAPIFactory().getUnfiledContainersAPI(nonRMuser).getUnfiledContainer(containerAlias);
}
// Check the response status code is FORBIDDEN
assertStatusCode(FORBIDDEN);

View File

@@ -29,11 +29,11 @@ package org.alfresco.rest.rm.community.fileplancomponents;
import static org.alfresco.rest.rm.community.base.TestData.ELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.base.TestData.NONELECTRONIC_RECORD_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.HOLDS_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.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;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createTempFile;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
@@ -43,13 +43,21 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import java.util.List;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentContent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.fileplancomponents.RecordBodyFile;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RecordsAPI;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordBodyFile;
import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildEntry;
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.RecordCategoryAPI;
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.utility.report.Bug;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -63,14 +71,14 @@ import org.testng.annotations.Test;
*/
public class FileRecordsTests extends BaseRMRestTest
{
private FilePlanComponent electronicRecord = FilePlanComponent.builder()
private UnfiledContainerChild electronicRecord = UnfiledContainerChild.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE.toString())
.content(FilePlanComponentContent.builder().mimeType("text/plain").build())
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
private FilePlanComponent nonelectronicRecord = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
private UnfiledContainerChild nonelectronicRecord = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
@@ -78,126 +86,170 @@ public class FileRecordsTests extends BaseRMRestTest
.nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
.build();
/**
* Unfiled containers from where record can be filed
*/
@DataProvider (name = "unfiledContainer")
public Object[][] getUnfiledContainer() throws Exception
{
return new Object[][] {
//unfiled container
{ getFilePlanComponent(UNFILED_RECORDS_CONTAINER_ALIAS).getId() },
// an arbitrary unfiled records folder
{ createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS.toString(), "Unfiled Folder " + getRandomAlphanumeric()).getId() }
};
}
/**
* Invalid containers where electronic and non-electronic records can be filed
*/
@DataProvider (name = "invalidContainersForFile")
public Object[][] getFolderContainers() throws Exception
public String[][] getFolderContainers() throws Exception
{
return new Object[][] {
{ getFilePlanComponent(FILE_PLAN_ALIAS).getId()},
{ getFilePlanComponent(UNFILED_RECORDS_CONTAINER_ALIAS).getId()},
{ getFilePlanComponent(HOLDS_ALIAS).getId() },
{ getFilePlanComponent(TRANSFERS_ALIAS).getId() },
return new String[][] {
{ FILE_PLAN_ALIAS},
{ UNFILED_RECORDS_CONTAINER_ALIAS},
{ TRANSFERS_ALIAS },
// an arbitrary record category
{ createCategory(getAdminUser(), FILE_PLAN_ALIAS, "Category " + getRandomAlphanumeric()).getId()},
{ createRootCategory(getAdminUser(), "Category " + getRandomAlphanumeric()).getId()},
// an arbitrary unfiled records folder
{ createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS.toString(), "Unfiled Folder " + getRandomAlphanumeric()).getId() }
{ createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId() }
};
}
/**
* Given an unfiled record in the root unfiled record container or a unfiled record folder
* 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
(
dataProvider = "unfiledContainer",
description = "File record from unfiled containers "
)
public void fileRecordIntoExistingFolder(String unfiledContainerId) throws Exception
public void fileRecordIntoExistingFolderFromUnfiledContainer() throws Exception
{
// get API instances
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
// create records
FilePlanComponent recordElectronic = filePlanComponentAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), unfiledContainerId);
FilePlanComponent recordNonElectId = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, unfiledContainerId);
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();
FilePlanComponent recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(),folderId);
// check the record is filed into the record folder
assertTrue(filePlanComponentAPI.listChildComponents(folderId)
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c->c.getFilePlanComponentModel().getId().equals(recordElectronic.getId())));
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(filePlanComponentAPI.listChildComponents(unfiledContainerId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordElectronic.getId())));
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
FilePlanComponent nonElectRecordFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElectId.getId());
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(filePlanComponentAPI.listChildComponents(folderId)
assertTrue(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordNonElectId.getId())));
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(filePlanComponentAPI.listChildComponents(unfiledContainerId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordNonElectId.getId())));
assertFalse(unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.anyMatch(c -> c.getEntry().getId().equals(recordNonElect.getId())));
}
/**
* Given an unfiled record in the root unfiled record container or a unfiled record folder
* Given an unfiled record in a unfiled record folder
* And an open record folder
* When I file the unfiled record into the record folder
* Then the record is filed
*/
@Test
public void fileRecordIntoExistingFolderFromUnfiledRecordFolder() 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());
// check the response status
assertStatusCode(CREATED);
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(),folderId);
// 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 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())));
}
/**
* Given an unfiled record in the root unfiled record container
* And a closed record folder
* When I file the unfiled record into the record folder
* Then I get an unsupported operation exception
*
*/
@Test
(
dataProvider = "unfiledContainer",
description = "File record from unfiled containers into a closed folder "
)
public void fileRecordIntoCloseFolder(String unfiledContainerId) throws Exception
public void fileRecordIntoCloseFolderFromUnfiledContainer() throws Exception
{
// get API instances
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String folderId = createCategoryFolderInFilePlan().getId();
closeFolder(folderId);
// create records
FilePlanComponent recordElectronic = filePlanComponentAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), unfiledContainerId);
FilePlanComponent recordNonElectId = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, unfiledContainerId);
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();
@@ -205,33 +257,93 @@ public class FileRecordsTests extends BaseRMRestTest
// check the response status
assertStatusCode(FORBIDDEN);
// check the record is filed into the record folder
assertFalse(filePlanComponentAPI.listChildComponents(folderId)
// check the record is not filed into the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordElectronic.getId())));
// check the record doesn't exist into unfiled record container
assertTrue(filePlanComponentAPI.listChildComponents(unfiledContainerId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordElectronic.getId())));
.anyMatch(c -> c.getEntry().getId().equals(recordElectronic.getId())));
// 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, recordNonElectId.getId());
recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status code
assertStatusCode(FORBIDDEN);
// check the record is added into the record folder
assertFalse(filePlanComponentAPI.listChildComponents(folderId)
// check the record is not added into the record folder
assertFalse(recordFolderAPI.getRecordFolderChildren(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordNonElectId.getId())));
// check the record doesn't exist into unfiled record container
assertTrue(filePlanComponentAPI.listChildComponents(unfiledContainerId)
.getEntries().stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordNonElectId.getId())));
.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())));
}
/**
* Given an unfiled record in a unfiled record folder
* And a closed record folder
* When I file the unfiled record into the record folder
* Then I get an unsupported operation exception
*
*/
@Test
public void fileRecordIntoCloseFolderFromUnfiledRecordFolder() throws Exception
{
// 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());
// 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 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())));
}
/**
@@ -245,20 +357,20 @@ public class FileRecordsTests extends BaseRMRestTest
public void linkRecordInto() throws Exception
{
// get API instances
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String parentFolderId = createCategoryFolderInFilePlan().getId();
// create records
FilePlanComponent recordElectronic = filePlanComponentAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), UNFILED_RECORDS_CONTAINER_ALIAS);
FilePlanComponent recordNonElect = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
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();
FilePlanComponent recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
FilePlanComponent nonElectronicFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
Record recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
Record nonElectronicFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElect.getId());
// check the response status
assertStatusCode(CREATED);
@@ -269,41 +381,43 @@ public class FileRecordsTests extends BaseRMRestTest
// check the response status
assertStatusCode(CREATED);
// link the electronic record
FilePlanComponent recordLink = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
Record recordLink = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
assertTrue(recordLink.getParentId().equals(parentFolderId));
// check the response status code
assertStatusCode(CREATED);
// link the nonelectronic record
FilePlanComponent nonElectronicLink = recordsAPI.fileRecord(recordBodyFile, nonElectronicFiled.getId());
Record nonElectronicLink = recordsAPI.fileRecord(recordBodyFile, nonElectronicFiled.getId());
assertStatusCode(CREATED);
assertTrue(nonElectronicLink.getParentId().equals(parentFolderId));
// check the record is added into the record folder
assertTrue(filePlanComponentAPI.listChildComponents(parentFolderId)
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertTrue(recordFolderAPI.getRecordFolderChildren(parentFolderId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordFiled.getId()) &&
c.getFilePlanComponentModel().getParentId().equals(parentFolderId)));
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId()) &&
c.getEntry().getParentId().equals(parentFolderId)));
// check the record doesn't exist into unfiled record container
// TODO add a check after the issue will be fixed RM-4578
assertTrue(filePlanComponentAPI.listChildComponents(folderToLink)
assertTrue(recordFolderAPI.getRecordFolderChildren(folderToLink)
.getEntries().stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordFiled.getId())));
.anyMatch(c -> c.getEntry().getId().equals(recordFiled.getId())));
// check the record is added into the record folder
assertTrue(filePlanComponentAPI.listChildComponents(parentFolderId)
.getEntries().stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(nonElectronicFiled.getId()) &&
c.getFilePlanComponentModel().getParentId().equals(parentFolderId)));
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
// TODO add a check after the issue will be fixed RM-4578
assertTrue(filePlanComponentAPI.listChildComponents(folderToLink)
assertTrue(recordFolderAPI.getRecordFolderChildren(folderToLink)
.getEntries().stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(nonElectronicFiled.getId())));
.anyMatch(c -> c.getEntry().getId().equals(nonElectronicFiled.getId())));
}
/**
* Given an unfiled or filed record
* And a container that is NOT a record folder
@@ -313,17 +427,18 @@ public class FileRecordsTests extends BaseRMRestTest
@Test
(
dataProvider = "invalidContainersForFile",
description = "File the unfiled record to the container that is not a record foldr"
description = "File the unfiled record to the container that is not a record folder"
)
public void invalidContainerToFile(String containerId) throws Exception
{
// get API instances
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create records
FilePlanComponent recordElectronic = filePlanComponentAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), UNFILED_RECORDS_CONTAINER_ALIAS);
FilePlanComponent recordNonElect = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
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();
@@ -334,70 +449,4 @@ public class FileRecordsTests extends BaseRMRestTest
// check the response status
assertStatusCode(BAD_REQUEST);
}
/**
* Given an unfiled record in the root unfiled record container or a unfiled record folder
* When I file the unfiled record into the record folder using the relativePath
* Then the filePlan structure from relativePath is created and the record is filed into the specified path
*/
@Test
(
dataProvider = "unfiledContainer",
description = "File record from unfiled containers "
)
public void fileRecordIntoRelativePath(String unfiledContainerId) throws Exception
{
// get API instances
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
// create a record folder
String RELATIVE_PATH = "CATEGORY" + getRandomAlphanumeric() + "/FOLDER";
// create records
FilePlanComponent recordElectronic = filePlanComponentAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), unfiledContainerId);
FilePlanComponent recordNonElectId = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, unfiledContainerId);
// file the record into the folder created
RecordBodyFile recordBodyFile = RecordBodyFile.builder().relativePath(RELATIVE_PATH).build();
FilePlanComponent recordFiled = recordsAPI.fileRecord(recordBodyFile, recordElectronic.getId());
// check the response status
assertStatusCode(CREATED);
// get the folder ID created
String folderId = filePlanComponentAPI.getFilePlanComponent(FILE_PLAN_ALIAS, "relativePath="+RELATIVE_PATH).getId();
// check the parent id for the record returned
assertEquals(recordFiled.getParentId(), folderId);
// check the record is filed into the record folder
assertTrue(filePlanComponentAPI.listChildComponents(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordElectronic.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(filePlanComponentAPI.listChildComponents(unfiledContainerId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordElectronic.getId())));
// file the non-electronic record into the folder created
FilePlanComponent nonElectRecordFiled = recordsAPI.fileRecord(recordBodyFile, recordNonElectId.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(filePlanComponentAPI.listChildComponents(folderId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordNonElectId.getId())));
// check the record doesn't exist into unfiled record container
assertFalse(filePlanComponentAPI.listChildComponents(unfiledContainerId)
.getEntries()
.stream()
.anyMatch(c -> c.getFilePlanComponentModel().getId().equals(recordNonElectId.getId())));
}
}

View File

@@ -26,32 +26,37 @@
*/
package org.alfresco.rest.rm.community.fileplancomponents;
import static java.lang.Integer.MAX_VALUE;
import static java.util.Arrays.asList;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.HOLDS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.NON_ELECTRONIC_RECORD_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.util.PojoUtility.toJson;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createFullNonElectronicUnfiledContainerChildRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createFullNonElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.verifyFullNonElectronicRecord;
import static org.alfresco.utility.constants.UserRole.SiteManager;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.util.Random;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordProperties;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
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.utility.constants.UserRole;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
@@ -65,45 +70,6 @@ import org.testng.annotations.Test;
*/
public class NonElectronicRecordTests extends BaseRMRestTest
{
/**
* <pre>
* Given a parent container that is NOT a record folder or an unfiled record folder
* When I try to create a non-electronic record within the parent container
* Then nothing happens
* And an error is reported
* </pre>
* @throws Exception if prerequisites can't be created
*/
@Test(description = "Non-electronic record can't be created as a child of invalid parent Id")
public void cantCreateForInvalidParentIds() throws Exception
{
// create record category, non-electronic records can't be its children
FilePlanComponent recordCategoryModel = FilePlanComponent.builder()
.name("Category " + getRandomAlphanumeric())
.nodeType(RECORD_CATEGORY_TYPE)
.build();
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent recordCategory = filePlanComponentsAPI.createFilePlanComponent(recordCategoryModel, FILE_PLAN_ALIAS);
// iterate through all invalid parent containers and try to create/file an electronic record
asList(FILE_PLAN_ALIAS, TRANSFERS_ALIAS, HOLDS_ALIAS, recordCategory.getId())
.stream()
.forEach(id ->
{
try
{
filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), id);
}
catch (Exception error)
{
}
// Verify the status code
assertStatusCode(UNPROCESSABLE_ENTITY);
});
}
/**
* <pre>
* Given a parent container that is a record folder
@@ -114,6 +80,8 @@ public class NonElectronicRecordTests extends BaseRMRestTest
* <pre>
* and
* <pre>
*
*
* Given a parent container that is an unfiled record folder or the root unfiled record container
* When I try to create a non-electronic record within the parent container
* Then the non-electronic record is created
@@ -126,67 +94,68 @@ public class NonElectronicRecordTests extends BaseRMRestTest
dataProvider = "validRootContainers",
description = "Non-electronic records can be created in valid containers"
)
public void canCreateInValidContainers(FilePlanComponent container) throws Exception
public void canCreateInValidContainers(String folderId, String type) throws Exception
{
logger.info("Root container:\n" + toJson(container));
logger.info("Root container:\n" + toJson(folderId));
if (container.getNodeType().equals(RECORD_FOLDER_TYPE))
{
// only record folders can be open or closed
assertFalse(container.getProperties().getIsClosed());
}
// use these properties for non-electronic record to be created
// Use these properties for non-electronic record to be created
String title = "Title " + getRandomAlphanumeric();
String description = "Description " + getRandomAlphanumeric();
String box = "Box "+ getRandomAlphanumeric();
String file = "File " + getRandomAlphanumeric();
String shelf = "Shelf " + getRandomAlphanumeric();
String location = "Location " + getRandomAlphanumeric();
String storageLocation = "Storage Location " + getRandomAlphanumeric();
String name = "Record " + getRandomAlphanumeric();
Random random = new Random();
Integer copies = random.nextInt(Integer.MAX_VALUE);
Integer size = random.nextInt(Integer.MAX_VALUE);
Integer numberOfCopies = random.nextInt(MAX_VALUE);
Integer physicalSize = random.nextInt(MAX_VALUE);
// set values of all available properties for the non electronic records
FilePlanComponent filePlanComponent = FilePlanComponent.builder()
.name(name)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.properties(FilePlanComponentProperties.builder()
.title(title)
.description(description)
.box(box)
.file(file)
.shelf(shelf)
.location(location)
.numberOfCopies(copies)
.physicalSize(size)
.build())
.build();
String nonElectronicId;
if (RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
// Only record folders can be opened or closed
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolder(folderId).getProperties().getIsClosed());
// create non-electronic record
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
String nonElectronicId = filePlanComponentsAPI.createFilePlanComponent(
filePlanComponent,
container.getId()).getId();
// Set values of all available properties for the non electronic records
Record nonElectrinicRecordModel = createFullNonElectronicRecordModel(name, title, description, box, file, shelf, storageLocation, numberOfCopies, physicalSize);
// verify the create request status code
// Create non-electronic record
nonElectronicId = recordFolderAPI.createRecord(nonElectrinicRecordModel, folderId).getId();
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
// Set values of all available properties for the non electronic records
UnfiledContainerChild nonElectrinicRecordModel = createFullNonElectronicUnfiledContainerChildRecordModel(name, title, description, box, file, shelf,
storageLocation, numberOfCopies, physicalSize);
// Create non-electronic record
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
nonElectronicId = unfiledContainersAPI.createUnfiledContainerChild(nonElectrinicRecordModel, folderId).getId();
}
else if(UNFILED_RECORD_FOLDER_TYPE.equalsIgnoreCase(type))
{
// Set values of all available properties for the non electronic records
UnfiledContainerChild nonElectrinicRecordModel = createFullNonElectronicUnfiledContainerChildRecordModel(name, title, description, box, file, shelf,
storageLocation, numberOfCopies, physicalSize);
// Create non-electronic record
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
nonElectronicId = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonElectrinicRecordModel, folderId).getId();
}
else
{
throw new Exception("Unsuported type = " + type);
}
// Verify the create request status code
assertStatusCode(CREATED);
// get newly created non-electonic record and verify its properties
FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.getFilePlanComponent(nonElectronicId);
assertEquals(title, nonElectronicRecord.getProperties().getTitle());
assertEquals(description, nonElectronicRecord.getProperties().getDescription());
assertEquals(box, nonElectronicRecord.getProperties().getBox());
assertEquals(file, nonElectronicRecord.getProperties().getFile());
assertEquals(shelf, nonElectronicRecord.getProperties().getShelf());
assertEquals(location, nonElectronicRecord.getProperties().getLocation());
assertEquals(copies, nonElectronicRecord.getProperties().getNumberOfCopies());
assertEquals(size, nonElectronicRecord.getProperties().getPhysicalSize());
assertTrue(nonElectronicRecord.getName().contains(nonElectronicRecord.getProperties().getRmIdentifier()));
assertTrue(nonElectronicRecord.getName().contains(name));
// Get newly created non-electronic record and verify its properties
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
Record nonElectronicRecord = recordsAPI.getRecord(nonElectronicId);
verifyFullNonElectronicRecord(nonElectronicRecord, name, title, description, box, file, shelf, storageLocation, numberOfCopies, physicalSize);
}
/**
@@ -197,23 +166,23 @@ public class NonElectronicRecordTests extends BaseRMRestTest
* Then nothing happens
* And an error is reported
* </pre>
* @throws Exception if prerequisites can't be created
* @throws Exception if record can't be created
*/
@Test(description = "Non-electronic record can't be created in closed record folder")
public void cantCreateInClosedFolder() throws Exception
{
FilePlanComponent recordFolder = createCategoryFolderInFilePlan();
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
// the folder should be open
// The folder should be open
assertFalse(recordFolder.getProperties().getIsClosed());
// close the folder
// Close the folder
closeFolder(recordFolder.getId());
// try to create it, this should fail and throw an exception
getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(createNonElectronicRecordModel(), recordFolder.getId());
// Try to create it, this should fail and throw an exception
getRestAPIFactory().getRecordFolderAPI().createRecord(createNonElectronicRecordModel(), recordFolder.getId());
// verify the status code
// Verify the status code
assertStatusCode(UNPROCESSABLE_ENTITY);
}
@@ -228,61 +197,139 @@ public class NonElectronicRecordTests extends BaseRMRestTest
* </pre>
* and
* <pre>
*
* Given a parent container that is an unfiled record folder or the root unfiled record container
* When I try to create a non-electronic record within the parent container
* And I do not provide all the required mandatory property values
* Then nothing happens
* And an error is reported
* </pre>
* @throws Exception if prerequisites can't be created
* @throws Exception if record can't be created
*/
@Test
(
dataProvider = "validRootContainers",
description = "Non-electronic record can only be created if all mandatory properties are given"
)
public void allMandatoryPropertiesRequired(FilePlanComponent container) throws Exception
public void allMandatoryPropertiesRequired(String folderId, String type) throws Exception
{
logger.info("Root container:\n" + toJson(container));
if (container.getNodeType().equals(RECORD_FOLDER_TYPE))
logger.info("Root container:\n" + toJson(folderId));
if (type.equals(RECORD_FOLDER_TYPE))
{
// only record folders can be open or closed
assertFalse(container.getProperties().getIsClosed());
// Only record folders can be opened or closed
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
assertFalse(recordFolderAPI.getRecordFolder(folderId).getProperties().getIsClosed());
// Component without name and title
Record noNameOrTitle = Record.builder().nodeType(NON_ELECTRONIC_RECORD_TYPE).build();
// Component with title only
Record titleOnly = Record.builder()
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.properties(RecordProperties.builder()
.title("Title " + getRandomAlphanumeric())
.build())
.build();
// Try to create invalid components
asList(noNameOrTitle, titleOnly).stream().forEach(c ->
{
try
{
logger.info("Creating non-electronic record with body:\n" + toJson(c));
}
catch (Exception error)
{
}
// This should fail and throw an exception
try
{
getRestAPIFactory().getRecordFolderAPI().createRecord(c, folderId);
}
catch (Exception e)
{
}
// Verify the status code is BAD_REQUEST
assertStatusCode(BAD_REQUEST);
});
}
// component without name and title
FilePlanComponent noNameOrTitle = getDummyNonElectronicRecord();
// component with title only
FilePlanComponent titleOnly = getDummyNonElectronicRecord();
FilePlanComponentProperties properties = FilePlanComponentProperties.builder()
.title("Title " + getRandomAlphanumeric())
.build();
titleOnly.setProperties(properties);
// try to create invalid components
asList(noNameOrTitle, titleOnly).stream().forEach(c ->
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
try
{
logger.info("Creating non-electronic record with body:\n" + toJson(c));
}
catch (Exception error)
{
}
// Component without name and title
UnfiledContainerChild noNameOrTitle = UnfiledContainerChild.builder().nodeType(NON_ELECTRONIC_RECORD_TYPE).build();
// this should fail and throw an exception
try
{
getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(c, container.getId());
}
catch (Exception e)
{
}
// Component with title only
UnfiledContainerChild titleOnly = UnfiledContainerChild.builder()
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.properties(UnfiledContainerChildProperties.builder()
.title("Title " + getRandomAlphanumeric())
.build())
.build();
// verify the status code is BAD_REQUEST
assertStatusCode(BAD_REQUEST);
});
// Try to create invalid components
asList(noNameOrTitle, titleOnly).stream().forEach(c ->
{
try
{
logger.info("Creating non-electronic record with body:\n" + toJson(c));
}
catch (Exception error)
{
}
// This should fail and throw an exception
try
{
getRestAPIFactory().getUnfiledContainersAPI().createUnfiledContainerChild(c, folderId);
}
catch (Exception e)
{
}
// Verify the status code is BAD_REQUEST
assertStatusCode(BAD_REQUEST);
});
}
else
{
//we have unfiled record folder type
// Component without name and title
UnfiledContainerChild noNameOrTitle = UnfiledContainerChild.builder().nodeType(NON_ELECTRONIC_RECORD_TYPE).build();
// Component with title only
UnfiledContainerChild titleOnly = UnfiledContainerChild.builder()
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.properties(UnfiledContainerChildProperties.builder()
.title("Title " + getRandomAlphanumeric())
.build())
.build();
// Try to create invalid components
asList(noNameOrTitle, titleOnly).stream().forEach(c ->
{
try
{
logger.info("Creating non-electronic record with body:\n" + toJson(c));
}
catch (Exception error)
{
}
// This should fail and throw an exception
try
{
getRestAPIFactory().getUnfiledRecordFoldersAPI().createUnfiledRecordFolderChild(c, folderId);
}
catch (Exception e)
{
}
// Verify the status code is BAD_REQUEST
assertStatusCode(BAD_REQUEST);
});
}
}
/**
@@ -292,62 +339,93 @@ public class NonElectronicRecordTests extends BaseRMRestTest
* Then nothing happens
* And an error is reported
* </pre>
* @throws Exception
* @throws Exception if record can't be created
*/
@Test
(
dataProvider = "validRootContainers",
description = "Non-electronic record can't be created if user doesn't have RM privileges"
)
public void cantCreateIfNoRmPrivileges(FilePlanComponent container) throws Exception
public void cantCreateIfNoRmPrivileges(String folderId, String type) throws Exception
{
UserModel user = createUserWithRole("zzzuser", SiteManager);
// try to create a fileplan component
FilePlanComponent record = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.description("Description")
.title("Title")
.build())
.name("Record Name")
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
// this should fail and throw an exception
try
if (type.equals(RECORD_FOLDER_TYPE))
{
getRestAPIFactory().getFilePlanComponentsAPI(user).createFilePlanComponent(record, container.getId());
}
catch (Exception e)
{
}
// Try to create a record model
Record recordModel = Record.builder()
.properties(RecordProperties.builder()
.description("Description")
.title("Title")
.build())
.name("Record Name")
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
// user who isn't an RM site member can't access the container path
// This should fail and throw an exception
try
{
getRestAPIFactory().getRecordFolderAPI(user).createRecord(recordModel, folderId);
}
catch (Exception e)
{
}
}
else if(UNFILED_CONTAINER_TYPE.equalsIgnoreCase(type))
{
// Try to create a record model
UnfiledContainerChild recordModel = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description("Description")
.title("Title")
.build())
.name("Record Name")
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
// This should fail and throw an exception
try
{
getRestAPIFactory().getUnfiledContainersAPI(user).createUnfiledContainerChild(recordModel, folderId);
}
catch (Exception e)
{
}
}
else
{
// Try to create a record model
UnfiledContainerChild recordModel = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description("Description")
.title("Title")
.build())
.name("Record Name")
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
// This should fail and throw an exception
try
{
getRestAPIFactory().getUnfiledRecordFoldersAPI(user).createUnfiledRecordFolderChild(recordModel, folderId);
}
catch (Exception e)
{
}
}
// User who isn't an RM site member can't access the container path
assertStatusCode(FORBIDDEN);
}
/**
* Helper function to return an empty FilePlanComponent for non-electronic record
* @return
*/
private FilePlanComponent getDummyNonElectronicRecord()
{
FilePlanComponent component = FilePlanComponent.builder()
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
return component;
}
/**
* Create user with given role and add it to RM site
* <br>
* Checks whether the user exists in RM site and creates it if required, with password identical
* to username. Note the role is a Core API role, not an RM role.
* to user name. Note the role is a Core API role, not an RM role.
* <br>
* For already existing users, no site membership or role verification is performed.
* <p>
* @param userName username to add
* @param userName user name to add
* @param userRole user's role
* @throws Exception
*/
@@ -355,17 +433,15 @@ public class NonElectronicRecordTests extends BaseRMRestTest
{
String siteId = getRestAPIFactory().getRMSiteAPI().getSite().getId();
// check if user exists
// Check if user exists
UserModel user = new UserModel();
user.setUsername(userName);
user.setPassword(userName);
if (!getDataUser().isUserInRepo(userName))
{
// user doesn't exist, create it
// User doesn't exist, create it
user = getDataUser().createUser(userName, userName);
user.setUserRole(userRole);
getDataUser().addUserToSite(user, new SiteModel(siteId), userRole);
}

View File

@@ -26,17 +26,23 @@
*/
package org.alfresco.rest.rm.community.fileplancomponents;
import static org.alfresco.rest.rm.community.base.TestData.FOLDER_NAME;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_CATEGORY_NAME;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_CATEGORY_TITLE;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_FOLDER_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.HOLDS_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.FilePlanComponentFields.IS_COMPLETED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.CONTENT;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PATH;
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;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordCategoryModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createTempFile;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;
@@ -46,55 +52,56 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
import static org.testng.AssertJUnit.assertTrue;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import com.google.common.io.Resources;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.TestData;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentContent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentsCollection;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RecordsAPI;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordContent;
import org.alfresco.rest.rm.community.model.record.RecordProperties;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderCollection;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildCollection;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
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.UnfiledRecordFolderAPI;
import org.apache.commons.codec.digest.DigestUtils;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* This class contains the tests for
* Read Records API
* This class contains the tests for Read Records API
*
* @author Rodica Sutu
* @since 2.6
*/
public class ReadRecordTests extends BaseRMRestTest
{
String CATEGORY_NAME=TestData.CATEGORY_NAME +getRandomAlphanumeric();
public static final String CATEGORY_NAME = TestData.RECORD_CATEGORY_NAME + getRandomAlphanumeric();
String ELECTRONIC_RECORD_NAME = "Record electronic" + getRandomAlphanumeric();
String NONELECTRONIC_RECORD_NAME = "Record nonelectronic" + getRandomAlphanumeric();
public static final String ELECTRONIC_RECORD_NAME = "Record electronic" + getRandomAlphanumeric();
public static final String NONELECTRONIC_RECORD_NAME = "Record nonelectronic" + getRandomAlphanumeric();
private FilePlanComponent electronicRecord = FilePlanComponent.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE.toString())
.content(FilePlanComponentContent.builder().mimeType("text/plain").build())
.build();
private FilePlanComponent nonelectronicRecord = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE.toString())
.build();
private Record electronicRecord = Record.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.build();
private Record nonelectronicRecord = Record.builder()
.properties(RecordProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
/**
* Given a record category or a container which can't contain records
@@ -102,12 +109,11 @@ public class ReadRecordTests extends BaseRMRestTest
* Then I receive an empty list
*/
@DataProvider(name="invalidContainersForRecords")
public Object[][] getInvalidContainersForRecords() throws Exception
public String[][] getInvalidContainersForRecords() throws Exception
{
return new Object[][] {
return new String[][] {
{ FILE_PLAN_ALIAS },
{ TRANSFERS_ALIAS },
{ HOLDS_ALIAS },
{ createCategoryFolderInFilePlan().getParentId()}
};
}
@@ -118,31 +124,54 @@ public class ReadRecordTests extends BaseRMRestTest
)
public void readRecordsFromInvalidContainers(String container) throws Exception
{
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent electronicRecord = FilePlanComponent.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(FilePlanComponentContent.builder().mimeType("text/plain").build())
.build();
FilePlanComponent nonelectronicRecord = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.description("Description")
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
Record electronicRecord = Record.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(RecordContent.builder().mimeType("text/plain").build())
.build();
Record nonelectronicRecord = Record.builder()
.properties(RecordProperties.builder()
.description("Description")
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
//create records
filePlanComponentAPI.createFilePlanComponent(electronicRecord, container);
filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, container);
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
recordFolderAPI.createRecord(electronicRecord, container);
assertStatusCode(BAD_REQUEST);
recordFolderAPI.createRecord(nonelectronicRecord, container);
assertStatusCode(BAD_REQUEST);
// List children from API
filePlanComponentAPI.listChildComponents(container, "where=(isFile=true)")
.assertThat()//check the list returned is empty
.entriesListIsEmpty().assertThat().paginationExist();
//check response status code
assertStatusCode(OK);
if(FILE_PLAN_ALIAS.equals(container))
{
getRestAPIFactory().getFilePlansAPI().getRootRecordCategories(container, "")
.assertThat()//check the list returned is not empty
.entriesListIsNotEmpty().assertThat().paginationExist();
//check response status code
assertStatusCode(OK);
}
else if(TRANSFERS_ALIAS.equals(container))
{
getRestAPIFactory().getTransferContainerAPI().getTransfers(container, "where=(isFile=true)")
.assertThat()//check the list returned is empty
.entriesListIsEmpty().assertThat().paginationExist();
//check response status code
assertStatusCode(OK);
}
else
{
String recordCategoryId = getRestAPIFactory().getRecordCategoryAPI().getRecordCategory(container).getId();
assertStatusCode(OK);
getRestAPIFactory().getRecordCategoryAPI().getRecordCategoryChildren(recordCategoryId)
.assertThat()//check the list returned is empty
.entriesListCountIs(1).assertThat().paginationExist();
String nodeType = getRestAPIFactory().getRecordCategoryAPI().getRecordCategoryChildren(recordCategoryId).getEntries().get(0).getEntry().getNodeType();
assertEquals(nodeType, RECORD_FOLDER_TYPE);
//check response status code
assertStatusCode(OK);
}
}
@@ -155,51 +184,49 @@ public class ReadRecordTests extends BaseRMRestTest
public void readRecordMetadata() throws Exception
{
String RELATIVE_PATH = "/" + CATEGORY_NAME + getRandomAlphanumeric() + "/folder";
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
//create the containers from the relativePath
FilePlanComponent recordFolder = FilePlanComponent.builder()
.name(FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(RELATIVE_PATH)
.build();
String folderId = filePlanComponentAPI.createFilePlanComponent(recordFolder, FILE_PLAN_ALIAS).getId();
//create electronic record
String recordWithContentId = filePlanComponentAPI.createElectronicRecord(electronicRecord, createTempFile(ELECTRONIC_RECORD_NAME, ELECTRONIC_RECORD_NAME), folderId).getId();
RecordCategory recordCategoryModel = createRecordCategoryModel(RECORD_CATEGORY_NAME, RECORD_CATEGORY_TITLE);
String recordCategoryId = getRestAPIFactory().getFilePlansAPI().createRootRecordCategory(recordCategoryModel, FILE_PLAN_ALIAS).getId();
//create the containers from the relativePath
RecordCategoryChild recordFolderModel = RecordCategoryChild.builder()
.name(RECORD_FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(RELATIVE_PATH)
.build();
String recordFolderId = getRestAPIFactory().getRecordCategoryAPI().createRecordCategoryChild(recordFolderModel, recordCategoryId, "include=" + PATH).getId();
//create electronic record
String recordWithContentId = getRestAPIFactory().getRecordFolderAPI().createRecord(electronicRecord, recordFolderId, getFile(IMAGE_FILE)).getId();
//Get the record created
FilePlanComponent recordWithContent= filePlanComponentAPI.getFilePlanComponent(recordWithContentId, "include = "+IS_COMPLETED);
Record recordWithContent= getRestAPIFactory().getRecordsAPI().getRecord(recordWithContentId, "include="+IS_COMPLETED +"," + CONTENT);
//Check the metadata returned
assertTrue(recordWithContent.getName().startsWith(ELECTRONIC_RECORD_NAME));
assertTrue(recordWithContent.getIsFile());
assertFalse(recordWithContent.getIsCategory());
assertFalse(recordWithContent.getIsRecordFolder());
assertNotNull(recordWithContent.getContent().getEncoding());
assertEquals(recordWithContent.getNodeType(),CONTENT_TYPE);
assertNotNull(recordWithContent.getContent().getEncoding());
assertNotNull(recordWithContent.getContent().getMimeType());
assertNotNull(recordWithContent.getAspectNames());
assertFalse(recordWithContent.getName().equals(ELECTRONIC_RECORD_NAME));
assertTrue(recordWithContent.getName().contains(recordWithContent.getProperties().getRmIdentifier()));
assertTrue(recordWithContent.getName().contains(recordWithContent.getProperties().getIdentifier()));
assertStatusCode(OK);
//create non-electronic record
String nonElectronicRecordId = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, folderId).getId();
String nonElectronicRecordId = getRestAPIFactory().getRecordFolderAPI().createRecord(nonelectronicRecord, recordFolderId).getId();
//Get the record created
FilePlanComponent nonElectronicRecord = filePlanComponentAPI.getFilePlanComponent(nonElectronicRecordId, "include = " + IS_COMPLETED);
Record nonElectronicRecord = getRestAPIFactory().getRecordsAPI().getRecord(nonElectronicRecordId, "include=" + IS_COMPLETED +"," + CONTENT);
//Check the metadata returned
assertTrue(nonElectronicRecord.getName().startsWith(NONELECTRONIC_RECORD_NAME));
assertTrue(nonElectronicRecord.getIsFile());
assertFalse(nonElectronicRecord.getIsCategory());
assertFalse(nonElectronicRecord.getIsRecordFolder());
assertNotNull(nonElectronicRecord.getContent().getEncoding());
assertEquals(nonElectronicRecord.getContent(), null);
assertEquals(nonElectronicRecord.getNodeType(), NON_ELECTRONIC_RECORD_TYPE);
assertNotNull(nonElectronicRecord.getContent().getEncoding());
assertNotNull(nonElectronicRecord.getContent().getMimeType());
assertNotNull(nonElectronicRecord.getAspectNames());
assertEquals(nonElectronicRecord.getProperties().getDescription(), NONELECTRONIC_RECORD_NAME);
assertFalse(nonElectronicRecord.getName().equals(NONELECTRONIC_RECORD_NAME));
assertTrue(nonElectronicRecord.getName().contains(nonElectronicRecord.getProperties().getRmIdentifier()));
assertTrue(nonElectronicRecord.getName().contains(nonElectronicRecord.getProperties().getIdentifier()));
assertStatusCode(OK);
}
@@ -211,43 +238,46 @@ public class ReadRecordTests extends BaseRMRestTest
@Test
public void readRecordContent() throws Exception
{
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
String RECORD_ELECTRONIC = "Record " + getRandomAlphanumeric();
String RECORD_ELECTRONIC_BINARY = "Binary Record" + getRandomAlphanumeric();
String existentRecordCategoryId = createCategoryFolderInFilePlan().getParentId();
String RELATIVE_PATH = "/" + CATEGORY_NAME + getRandomAlphanumeric() + "/folder";
// create the containers from the relativePath
FilePlanComponent recordFolder = FilePlanComponent.builder()
.name(FOLDER_NAME)
RecordCategoryChild recordFolder = RecordCategoryChild.builder()
.name(RECORD_FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(RELATIVE_PATH)
.build();
String folderId = filePlanComponentAPI.createFilePlanComponent(recordFolder, FILE_PLAN_ALIAS).getId();
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
String folderId = recordCategoryAPI.createRecordCategoryChild(recordFolder, existentRecordCategoryId).getId();
// text file as an electronic record
FilePlanComponent recordText = FilePlanComponent.builder()
.name(RECORD_ELECTRONIC)
.nodeType(CONTENT_TYPE)
.build();
String recordId = filePlanComponentAPI.createElectronicRecord(recordText, createTempFile(RECORD_ELECTRONIC, RECORD_ELECTRONIC), folderId).getId();
Record recordText = Record.builder()
.name(RECORD_ELECTRONIC)
.nodeType(CONTENT_TYPE)
.build();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
String recordId = recordFolderAPI.createRecord(recordText, folderId, createTempFile(RECORD_ELECTRONIC, RECORD_ELECTRONIC)).getId();
assertEquals(recordsAPI.getRecordContent(recordId).asString(), RECORD_ELECTRONIC);
// Check status code
assertStatusCode(OK);
// binary file as an electronic record
FilePlanComponent recordBinary = FilePlanComponent.builder()
Record recordBinary = Record.builder()
.name(RECORD_ELECTRONIC_BINARY)
.nodeType(CONTENT_TYPE)
.build();
String binaryRecordId = filePlanComponentAPI.createElectronicRecord(recordBinary, IMAGE_FILE, folderId).getId();
String binaryRecordId = recordFolderAPI.createRecord(recordBinary, folderId, getFile(IMAGE_FILE)).getId();
// binary content, therefore compare respective SHA1 checksums in order to verify this is identical content
try
(
InputStream recordContentStream = recordsAPI.getRecordContent(binaryRecordId).asInputStream();
FileInputStream localFileStream = new FileInputStream(new File(Resources.getResource(IMAGE_FILE).getFile()));
FileInputStream localFileStream = new FileInputStream(getFile(IMAGE_FILE));
)
{
assertEquals(DigestUtils.sha1(recordContentStream), DigestUtils.sha1(localFileStream));
@@ -255,11 +285,11 @@ public class ReadRecordTests extends BaseRMRestTest
assertStatusCode(OK);
// electronic record with no content
FilePlanComponent recordNoContent = FilePlanComponent.builder()
Record recordNoContent = Record.builder()
.name(RECORD_ELECTRONIC)
.nodeType(CONTENT_TYPE)
.build();
String recordNoContentId = filePlanComponentAPI.createFilePlanComponent(recordNoContent,folderId).getId();
String recordNoContentId = recordFolderAPI.createRecord(recordNoContent,folderId).getId();
assertTrue(recordsAPI.getRecordContent(recordNoContentId).asString().isEmpty());
assertStatusCode(OK);
}
@@ -273,18 +303,17 @@ public class ReadRecordTests extends BaseRMRestTest
{
String NONELECTRONIC_RECORD_NAME = "Record nonelectronic" + getRandomAlphanumeric();
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent record = FilePlanComponent.builder()
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.relativePath("/" + CATEGORY_NAME + getRandomAlphanumeric() + "/" + FOLDER_NAME)
.build();
String folderId = createCategoryFolderInFilePlan().getId();
Record record = Record.builder()
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
String nonElectronicRecord = filePlanComponentAPI.createFilePlanComponent(record, FILE_PLAN_ALIAS).getId();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
String nonElectronicRecord = recordFolderAPI.createRecord(record, folderId).getId();
assertTrue(getRestAPIFactory().getRecordsAPI().getRecordContent(nonElectronicRecord).asString().isEmpty());
assertStatusCode(OK);
getRestAPIFactory().getRecordsAPI().getRecordContent(nonElectronicRecord);
assertStatusCode(BAD_REQUEST);
}
/**
@@ -292,10 +321,18 @@ public class ReadRecordTests extends BaseRMRestTest
* When I try to read the content
* Then I receive an error
*/
@DataProvider(name="noContentNodes")
public String[][] getNonRecordTypes() throws Exception
{
return new String[][] {
{ getFilePlan(FILE_PLAN_ALIAS).getId() },
{ getTransferContainer(TRANSFERS_ALIAS).getId() },
{ createCategoryFolderInFilePlan().getParentId()}
};
}
@Test
(
dataProvider = "getContainers",
dataProviderClass = TestData.class,
dataProvider = "noContentNodes",
description = "Reading records from invalid containers"
)
public void readContentFromInvalidContainers(String container) throws Exception
@@ -305,64 +342,49 @@ public class ReadRecordTests extends BaseRMRestTest
}
/**
* Given a container that is a record/unfiled folder
* Given a container that is a record folder
* When I try to record the containers records
* Then I receive a list of all the records contained within the record/unfiled folder
* Then I receive a list of all the records contained within the record folder
*/
/** Valid root containers where electronic and non-electronic records can be created */
@DataProvider (name = "folderContainers")
public Object[][] getFolderContainers() throws Exception
{
return new Object[][] {
// an arbitrary record folder
{ createCategoryFolderInFilePlan().getId()},
// an arbitrary unfiled records folder
{ createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS.toString(), "Unfiled Folder " + getRandomAlphanumeric()).getId() }
};
}
@Test
(
dataProvider ="folderContainers",
description ="List the records from record folder/unfiled record folder"
)
public void readRecordsFromFolders(String containerId) throws Exception
public void readRecordsFromRecordFolder() throws Exception
{
final int NUMBER_OF_RECORDS = 5;
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
String containerId = createCategoryFolderInFilePlan().getId();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
// Create Electronic Records
ArrayList<FilePlanComponent> children = new ArrayList<FilePlanComponent>();
ArrayList<Record> children = new ArrayList<Record>();
for (int i = 0; i < NUMBER_OF_RECORDS; i++)
{
//build the electronic record
FilePlanComponent record = FilePlanComponent.builder()
.name(ELECTRONIC_RECORD_NAME +i)
.nodeType(CONTENT_TYPE)
.build();
Record record = Record.builder()
.name(ELECTRONIC_RECORD_NAME + i)
.nodeType(CONTENT_TYPE)
.build();
//create a child
FilePlanComponent child = filePlanComponentAPI.createElectronicRecord(record, createTempFile(ELECTRONIC_RECORD_NAME + i, ELECTRONIC_RECORD_NAME + i ), containerId);
Record child = recordFolderAPI.createRecord(record, containerId, createTempFile(ELECTRONIC_RECORD_NAME + i, ELECTRONIC_RECORD_NAME + i ));
children.add(child);
}
//Create NonElectronicRecords
for (int i = 0; i < NUMBER_OF_RECORDS; i++)
{
FilePlanComponent nonelectronicRecord = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.description("Description")
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME+i)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
Record nonelectronicRecord = Record.builder()
.properties(RecordProperties.builder()
.description("Description")
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME+i)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
//create records
FilePlanComponent child = filePlanComponentAPI.createFilePlanComponent(nonelectronicRecord, containerId);
Record child = recordFolderAPI.createRecord(nonelectronicRecord, containerId);
children.add(child);
}
// List children from API
FilePlanComponentsCollection apiChildren =
(FilePlanComponentsCollection) filePlanComponentAPI.listChildComponents(containerId).assertThat().entriesListIsNotEmpty();
RecordFolderCollection apiChildren = (RecordFolderCollection) recordFolderAPI.getRecordFolderChildren(containerId).assertThat().entriesListIsNotEmpty();
// Check status code
assertStatusCode(OK);
@@ -370,106 +392,123 @@ public class ReadRecordTests extends BaseRMRestTest
// Check listed children against created list
apiChildren.getEntries().forEach(c ->
{
Record record = c.getEntry();
assertNotNull(record.getId());
logger.info("Checking child " + record.getId());
try
{
FilePlanComponent filePlanComponent = c.getFilePlanComponentModel();
assertNotNull(filePlanComponent.getId());
logger.info("Checking child " + filePlanComponent.getId());
// Find this child in created children list
Record createdComponent = children.stream()
.filter(child -> child.getId().equals(record.getId()))
.findFirst()
.get();
try
{
// Find this child in created children list
FilePlanComponent createdComponent = children.stream()
.filter(child -> child.getId().equals(filePlanComponent.getId()))
.findFirst()
.get();
// Created by
assertEquals(record.getCreatedByUser().getId(), getAdminUser().getUsername());
// Created by
assertEquals(filePlanComponent.getCreatedByUser().getId(), getAdminUser().getUsername());
// Is parent Id set correctly
assertEquals(record.getParentId(), containerId);
// Is parent Id set correctly
assertEquals(filePlanComponent.getParentId(), containerId);
assertTrue(filePlanComponent.getIsFile());
//check the record name
assertTrue(record.getName().equals(createdComponent.getName()));
assertTrue(createdComponent.getName().contains(createdComponent.getProperties().getIdentifier()));
assertEquals(createdComponent.getNodeType(), record.getNodeType());
// Boolean properties related to node type
assertFalse(filePlanComponent.getIsRecordFolder());
assertFalse(filePlanComponent.getIsCategory());
//check the record name
assertTrue(filePlanComponent.getName().equals(createdComponent.getName()));
assertTrue(createdComponent.getName().contains(createdComponent.getProperties().getRmIdentifier()));
assertEquals(createdComponent.getNodeType(), filePlanComponent.getNodeType());
}
catch (NoSuchElementException e)
{
fail("No child element for " + filePlanComponent.getId());
}
}
);
catch (NoSuchElementException e)
{
fail("No child element for " + record.getId());
}
});
}
/**
* Given a record
* When I try to read the children
* Then I receive error
* Given a container that is a unfiled record folder
* When I try to record the containers records
* Then I receive a list of all the records contained within the unfiled record folder
*/
@Test
public void readChildrenOnRecords() throws Exception
public void readRecordsFromUnfiledRecordFolder() throws Exception
{
String RELATIVE_PATH = "CATEGORY" + getRandomAlphanumeric() + "/FOLDER";
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent electRecord = FilePlanComponent.builder()
.name(ELECTRONIC_RECORD_NAME)
.nodeType(CONTENT_TYPE)
.content(FilePlanComponentContent.builder().mimeType("text/plain").build())
.build();
FilePlanComponent nonElectronic = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.description(NONELECTRONIC_RECORD_NAME)
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
final int NUMBER_OF_RECORDS = 5;
String containerId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
//we have unfiled record folder
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
// Create Electronic Records
ArrayList<UnfiledContainerChild> children = new ArrayList<UnfiledContainerChild>();
for (int i = 0; i < NUMBER_OF_RECORDS; i++)
{
//build the electronic record
UnfiledContainerChild record = UnfiledContainerChild.builder()
.name(ELECTRONIC_RECORD_NAME + i)
.nodeType(CONTENT_TYPE)
.build();
//create a child
UnfiledContainerChild child = unfiledRecordFoldersAPI.uploadRecord(record, containerId, createTempFile(ELECTRONIC_RECORD_NAME + i, ELECTRONIC_RECORD_NAME + i ));
//create records in Unfiled Container
FilePlanComponent recordElecInUnfiled = filePlanComponentAPI.createFilePlanComponent(electRecord, UNFILED_RECORDS_CONTAINER_ALIAS);
FilePlanComponent recordNonElecInUnfiled = filePlanComponentAPI.createFilePlanComponent(nonElectronic, UNFILED_RECORDS_CONTAINER_ALIAS);
children.add(child);
}
//Create NonElectronicRecords
for (int i = 0; i < NUMBER_OF_RECORDS; i++)
{
UnfiledContainerChild nonelectronicRecord = UnfiledContainerChild.builder()
.properties(UnfiledContainerChildProperties.builder()
.description("Description")
.title("Title")
.build())
.name(NONELECTRONIC_RECORD_NAME+i)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
//create records
UnfiledContainerChild child = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(nonelectronicRecord, containerId);
children.add(child);
}
// List children from API
UnfiledContainerChildCollection apiChildren = (UnfiledContainerChildCollection) unfiledRecordFoldersAPI.getUnfiledRecordFolderChildren(containerId).assertThat().entriesListIsNotEmpty();
// List children for the electronic Record
filePlanComponentAPI.listChildComponents(recordElecInUnfiled.getId(), "where=(isFile=true)")
//check the list returned is empty
.assertThat().entriesListIsEmpty().assertThat().paginationExist();
// Check status code
assertStatusCode(OK);
// List children for the nonElectronic Record
filePlanComponentAPI.listChildComponents(recordNonElecInUnfiled.getId(), "where=(isFile=true)")
//check the list returned is empty
.assertThat().entriesListIsEmpty().assertThat().paginationExist();
// Check status code
assertStatusCode(OK);
//Update the Records objects
electRecord.setRelativePath(RELATIVE_PATH);
nonElectronic.setRelativePath(RELATIVE_PATH);
// Check listed children against created list
apiChildren.getEntries().forEach(c ->
{
UnfiledContainerChild record = c.getEntry();
assertNotNull(record.getId());
logger.info("Checking child " + record.getId());
//create records in Unfiled Container
FilePlanComponent recordElecFromRecordFolder = filePlanComponentAPI.createFilePlanComponent(electRecord, FILE_PLAN_ALIAS);
FilePlanComponent recordNonElecFromRecordFolder = filePlanComponentAPI.createFilePlanComponent(nonElectronic, FILE_PLAN_ALIAS);
try
{
// Find this child in created children list
UnfiledContainerChild createdComponent = children.stream()
.filter(child -> child.getId().equals(record.getId()))
.findFirst()
.get();
// List children for the electronic Record
filePlanComponentAPI.listChildComponents(recordElecFromRecordFolder.getId(), "where=(isFile=true)")
//check the list returned is empty
.assertThat().entriesListIsEmpty().assertThat().paginationExist();
// Check status code
assertStatusCode(OK);
// Created by
assertEquals(record.getCreatedByUser().getId(), getAdminUser().getUsername());
// List children for the nonElectronic Record
getRestAPIFactory().getFilePlanComponentsAPI().listChildComponents(recordNonElecFromRecordFolder.getId(), "where=(isFile=true)")
//check the list returned is empty
.assertThat().entriesListIsEmpty().assertThat().paginationExist();
// Check status code
assertStatusCode(OK);
// Is parent Id set correctly
assertEquals(record.getParentId(), containerId);
assertTrue(record.getIsRecord());
// Boolean properties related to node type
assertFalse(record.getIsUnfiledRecordFolder());
//check the record name
assertTrue(record.getName().equals(createdComponent.getName()));
assertTrue(createdComponent.getName().contains(createdComponent.getProperties().getIdentifier()));
assertEquals(createdComponent.getNodeType(), record.getNodeType());
}
catch (NoSuchElementException e)
{
fail("No child element for " + record.getId());
}
});
}
}

View File

@@ -1,411 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.fileplancomponents;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.TestData;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentsCollection;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.utility.report.Bug;
import org.testng.annotations.Test;
/**
* Record category related API tests
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
public class RecordCategoryTest extends BaseRMRestTest
{
// Number of children (for children creation test)
private static final int NUMBER_OF_CHILDREN = 10;
/**
* <pre>
* Given that a file plan exists
* When I ask the API to create a root record category
* Then it is created as a root record category
*
*
* Given that a file plan exists
* When I use the API to create a folder (cm:folder type) into the fileplan
* Then the folder is converted to rma:recordCategory
* (see RM-4572 comments)
*
*/
@Test
(
description = "Create root category",
dataProviderClass= TestData.class,
dataProvider = "categoryTypes"
)
public void createCategoryTest(String nodeType) throws Exception
{
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Build the record category properties
FilePlanComponent recordCategory = FilePlanComponent.builder()
.name(categoryName)
.nodeType(nodeType)
.properties(
FilePlanComponentProperties.builder()
.title(categoryTitle)
.build())
.build();
// Create the record category
FilePlanComponent filePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(recordCategory, FILE_PLAN_ALIAS);
// Verify the status code
assertStatusCode(CREATED);
// Verify the returned file plan component
assertTrue(filePlanComponent.getIsCategory());
assertFalse(filePlanComponent.getIsFile());
assertFalse(filePlanComponent.getIsRecordFolder());
assertEquals(filePlanComponent.getName(), categoryName);
assertEquals(filePlanComponent.getNodeType(), RECORD_CATEGORY_TYPE);
assertEquals(filePlanComponent.getCreatedByUser().getId(), getAdminUser().getUsername());
// Verify the returned file plan component properties
FilePlanComponentProperties filePlanComponentProperties = filePlanComponent.getProperties();
assertEquals(filePlanComponentProperties.getTitle(), categoryTitle);
assertNotNull(filePlanComponentProperties.getRmIdentifier());
logger.info("Aspects: " + filePlanComponent.getAspectNames());
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to update the details of the record category
* Then the details of the record category are updated
*/
@Test
(
description = "Rename root category"
)
public void renameCategory() throws Exception
{
// Create record category first
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Build the record category properties
FilePlanComponent recordCategory = FilePlanComponent.builder()
.name(categoryName)
.nodeType(RECORD_CATEGORY_TYPE)
.properties(
FilePlanComponentProperties.builder()
.title(categoryTitle)
.build())
.build();
// Create the record category
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent filePlanComponent = filePlanComponentsAPI.createFilePlanComponent(recordCategory, FILE_PLAN_ALIAS);
String newCategoryName = "Rename " + categoryName;
// Build the properties which will be updated
FilePlanComponent recordCategoryUpdated = FilePlanComponent.builder().name(newCategoryName).build();
// Update the record category
FilePlanComponent renamedFilePlanComponent = filePlanComponentsAPI.updateFilePlanComponent(recordCategoryUpdated, filePlanComponent.getId());
// Verify the status code
assertStatusCode(OK);
// Verify the returned file plan component
assertEquals(renamedFilePlanComponent.getName(), newCategoryName);
// Get actual FILE_PLAN_ALIAS id
FilePlanComponent parentComponent = filePlanComponentsAPI.getFilePlanComponent(FILE_PLAN_ALIAS);
// verify renamed component still has this parent
assertEquals(renamedFilePlanComponent.getParentId(), parentComponent.getId());
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to delete the record category
* Then the record category and all its contents is deleted
*/
@Test
(
description = "Delete category"
)
public void deleteCategory() throws Exception
{
// Create record category first
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Build the record category properties
FilePlanComponent recordCategory = FilePlanComponent.builder()
.name(categoryName)
.nodeType(RECORD_CATEGORY_TYPE)
.properties(
FilePlanComponentProperties.builder()
.title(categoryTitle)
.build())
.build();
// Create the record category
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent filePlanComponent = filePlanComponentsAPI.createFilePlanComponent(recordCategory, FILE_PLAN_ALIAS);
// Delete the record category
filePlanComponentsAPI.deleteFilePlanComponent(filePlanComponent.getId());
// Verify the status code
assertStatusCode(NO_CONTENT);
// Deleted component should no longer be retrievable
filePlanComponentsAPI.getFilePlanComponent(filePlanComponent.getId());
assertStatusCode(NOT_FOUND);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to create a record category
* Then it is created within the record category
*/
@Test
(
description = "Create child category"
)
public void createSubcategory() throws Exception
{
// Create root level category
FilePlanComponent rootCategory = createCategory(FILE_PLAN_ALIAS, getRandomAlphanumeric());
assertNotNull(rootCategory.getId());
// Create subcategory as a child of rootCategory
FilePlanComponent childCategory = createCategory(rootCategory.getId(), getRandomAlphanumeric());
// Child category created?
assertNotNull(childCategory.getId());
// Verify child category
assertEquals(childCategory.getParentId(), rootCategory.getId());
assertTrue(childCategory.getIsCategory());
assertFalse(childCategory.getIsFile());
assertFalse(childCategory.getIsRecordFolder());
assertEquals(childCategory.getNodeType(), RECORD_CATEGORY_TYPE);
}
/**
* <pre>
* Given that a record category exists
* And contains a number of record categories and record folders
* When I ask the APi to get me the children of the record category
* Then I am returned the contained record categories and record folders
* And their details
*/
@Test
(
description = "List children of a category"
)
public void listChildren() throws Exception
{
// Create root level category
FilePlanComponent rootCategory = createCategory(FILE_PLAN_ALIAS, getRandomAlphanumeric());
assertNotNull(rootCategory.getId());
// Add child categories/folders
ArrayList<FilePlanComponent> children = new ArrayList<FilePlanComponent>();
for (int i=0; i < NUMBER_OF_CHILDREN; i++)
{
// Create a child
FilePlanComponent child = createComponent(rootCategory.getId(),
getRandomAlphanumeric(),
// half of the children should be subcategories, the other subfolders
(i <= NUMBER_OF_CHILDREN / 2) ? RECORD_CATEGORY_TYPE : RECORD_FOLDER_TYPE);
assertNotNull(child.getId());
children.add(child);
}
// List children from API
FilePlanComponentsCollection apiChildren = getRestAPIFactory().getFilePlanComponentsAPI().listChildComponents(rootCategory.getId());
// Check status code
assertStatusCode(OK);
logger.info("parent: " + rootCategory.getId());
// Check listed children against created list
apiChildren.getEntries().forEach(c ->
{
FilePlanComponent filePlanComponent = c.getFilePlanComponentModel();
assertNotNull(filePlanComponent.getId());
logger.info("Checking child " + filePlanComponent.getId());
try
{
// Find this child in created children list
FilePlanComponent createdComponent = children.stream()
.filter(child -> child.getId().equals(filePlanComponent.getId()))
.findFirst()
.get();
// Created by
assertEquals(filePlanComponent.getCreatedByUser().getId(), getAdminUser().getUsername());
// Is parent Id set correctly?
assertEquals(filePlanComponent.getParentId(), rootCategory.getId());
// Only categories or folders have been created
assertFalse(filePlanComponent.getIsFile());
// Boolean properties related to node type
// Only RECORD_CATEGORY_TYPE and RECORD_FOLDER_TYPE have been created
if (filePlanComponent.getNodeType().equals(RECORD_CATEGORY_TYPE))
{
assertTrue(filePlanComponent.getIsCategory());
assertFalse(filePlanComponent.getIsRecordFolder());
}
else
{
assertTrue(filePlanComponent.getIsRecordFolder());
assertFalse(filePlanComponent.getIsCategory());
}
// Does returned object have the same contents as the created one?
assertEquals(createdComponent.getName(), filePlanComponent.getName());
assertEquals(createdComponent.getNodeType(), filePlanComponent.getNodeType());
// Verify properties
// FIXME: Verify properties
assertNotNull(createdComponent.getProperties().getRmIdentifier());
}
catch (NoSuchElementException e)
{
fail("No child element for " + filePlanComponent.getId());
}
});
}
/**
* Given that a record category exists
* When I ask to create a object type which is not a record category or a record folder as a child
* Then the children are not created and the 422 response code is returned
*/
@Test
(
description = "Create node types not allowed inside a category",
dataProviderClass = TestData.class,
dataProvider = "childrenNotAllowedForCategory"
)
@Bug (id="RM-4367, RM-4572")
public void createTypesNotAllowedInCategory(String nodeType) throws Exception
{
String COMPONENT_NAME = "Component"+getRandomAlphanumeric();
//Create the category
FilePlanComponent category = createCategory(FILE_PLAN_ALIAS, COMPONENT_NAME);
//Build node properties
FilePlanComponent recordCategory = FilePlanComponent.builder()
.name(COMPONENT_NAME)
.nodeType(nodeType)
.properties(
FilePlanComponentProperties.builder()
.title("Title for " + COMPONENT_NAME)
.build())
.build();
//create the invalid node type
getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(recordCategory, category.getId());
assertStatusCode(UNPROCESSABLE_ENTITY);
}
/**
* Helper method to create child category
*
* @param parentCategoryId The id of the parent category
* @param categoryName The name of the category
* @return The created category
* @throws Exception on unsuccessful component creation
*/
public FilePlanComponent createCategory(String parentCategoryId, String categoryName) throws Exception
{
return createComponent(parentCategoryId, categoryName, RECORD_CATEGORY_TYPE);
}
/**
* Helper method to create generic child component
*
* @param parentComponentId The id of the parent file plan component
* @param componentName The name of the file plan component
* @param componentType The name of the file plan component
* @return The created file plan component
* @throws Exception
*/
private FilePlanComponent createComponent(String parentComponentId, String componentName, String componentType) throws Exception
{
// Build node properties
FilePlanComponent component = FilePlanComponent.builder()
.name(componentName)
.nodeType(componentType)
.properties(FilePlanComponentProperties.builder()
.title("Title for " + componentName)
.build())
.build();
FilePlanComponent filePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(component, parentComponentId);
assertStatusCode(CREATED);
return filePlanComponent;
}
}

View File

@@ -0,0 +1,331 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.fileplancomponents;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_CATEGORY_NAME;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.TestData;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.utility.report.Bug;
import org.testng.annotations.Test;
/**
* Record category related API tests
*
* @author Kristijan Conkas
* @author Tuna Aksoy
* @since 2.6
*/
public class RecordCategoryTests extends BaseRMRestTest
{
/** Number of children (for children creation test) */
private static final int NUMBER_OF_CHILDREN = 10;
/**
* <pre>
* Given that a file plan exists
* When I ask the API to create a root record category
* Then it is created as a root record category
* </pre>
* <pre>
* Given that a file plan exists
* When I use the API to create a folder (cm:folder type) into the fileplan
* Then the folder is converted to rma:recordCategory
* (see RM-4572 comments)
* </pre>
*/
@Test
(
description = "Create root category",
dataProviderClass= TestData.class,
dataProvider = "categoryTypes"
)
public void createCategoryTest(String nodeType) throws Exception
{
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Create the root record category
RecordCategory rootRecordCategory = createRootCategory(categoryName, categoryTitle);
// Verify the status code
assertStatusCode(CREATED);
assertEquals(rootRecordCategory.getName(), categoryName);
assertEquals(rootRecordCategory.getNodeType(), RECORD_CATEGORY_TYPE);
assertEquals(rootRecordCategory.getCreatedByUser().getId(), getAdminUser().getUsername());
// Verify the returned root record category properties
RecordCategoryProperties rootRecordCategoryProperties = rootRecordCategory.getProperties();
assertEquals(rootRecordCategoryProperties.getTitle(), categoryTitle);
assertNotNull(rootRecordCategoryProperties.getIdentifier());
logger.info("Aspects: " + rootRecordCategory.getAspectNames());
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to update the details of the record category
* Then the details of the record category are updated
* </pre>
*/
@Test
(
description = "Rename root category"
)
public void renameCategory() throws Exception
{
// Create record category first
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Create the root record category
RecordCategory rootRecordCategory = createRootCategory(categoryName, categoryTitle);
String newCategoryName = "Rename " + categoryName;
// Build the properties which will be updated
RecordCategory recordCategoryUpdated = RecordCategory.builder().name(newCategoryName).build();
// Update the record category
RecordCategory renamedRecordCategory = getRestAPIFactory().getRecordCategoryAPI().updateRecordCategory(recordCategoryUpdated, rootRecordCategory.getId());
// Verify the status code
assertStatusCode(OK);
// Verify the returned file plan component
assertEquals(renamedRecordCategory.getName(), newCategoryName);
// Get actual FILE_PLAN_ALIAS id
FilePlan filePlan = getRestAPIFactory().getFilePlansAPI().getFilePlan(FILE_PLAN_ALIAS);
// verify renamed component still has this parent
assertEquals(renamedRecordCategory.getParentId(), filePlan.getId());
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to delete the record category
* Then the record category and all its contents are deleted
* </pre>
*/
@Test
(
description = "Delete category"
)
public void deleteCategory() throws Exception
{
// Create record category first
String categoryName = "Category name " + getRandomAlphanumeric();
String categoryTitle = "Category title " + getRandomAlphanumeric();
// Create the root record category
RecordCategory rootRecordCategory = createRootCategory(categoryName, categoryTitle);
// Delete the record category
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
String recordCategoryId = rootRecordCategory.getId();
recordCategoryAPI.deleteRecordCategory(recordCategoryId);
// Verify the status code
assertStatusCode(NO_CONTENT);
// Deleted component should no longer be retrievable
recordCategoryAPI.getRecordCategory(recordCategoryId);
assertStatusCode(NOT_FOUND);
}
/**
* <pre>
* Given that a record category exists
* When I ask the API to create a record category
* Then it is created within the record category
* </pre>
*/
@Test
(
description = "Create child category"
)
public void createSubcategory() throws Exception
{
// Create root level category
RecordCategory rootCategory = createRootCategory(getRandomAlphanumeric());
assertNotNull(rootCategory.getId());
// Create sub-category as a child of rootCategory
RecordCategoryChild recordCategory = createRecordCategoryChild(rootCategory.getId(), RECORD_CATEGORY_NAME, RECORD_CATEGORY_TYPE);
// Child category created?
assertNotNull(recordCategory.getId());
// Verify child category
assertEquals(recordCategory.getParentId(), rootCategory.getId());
assertTrue(recordCategory.getIsRecordCategory());
assertFalse(recordCategory.getIsRecordFolder());
assertEquals(recordCategory.getNodeType(), RECORD_CATEGORY_TYPE);
}
/**
* <pre>
* Given that a record category exists
* And contains a number of record categories and record folders
* When I ask the API to get me the children of the record category
* Then I am returned the contained record categories and record folders and their details
* </pre>
*/
@Test
(
description = "Get children of a record category"
)
public void getRecordCategoryChildren() throws Exception
{
// Create root level category
RecordCategory rootRecordCategory = createRootCategory(getRandomAlphanumeric());
assertNotNull(rootRecordCategory.getId());
// Add record category children
List<RecordCategoryChild> children = new ArrayList<RecordCategoryChild>();
for (int i=0; i < NUMBER_OF_CHILDREN; i++)
{
// Create a record category child
RecordCategoryChild child = createRecordCategoryChild(rootRecordCategory.getId(),
getRandomAlphanumeric(),
// half of the children should be sub-categories, the other sub-folders
(i <= NUMBER_OF_CHILDREN / 2) ? RECORD_CATEGORY_TYPE : RECORD_FOLDER_TYPE);
assertNotNull(child.getId());
children.add(child);
}
// Get children from API
RecordCategoryChildCollection recordCategoryChildren = getRestAPIFactory().getRecordCategoryAPI().getRecordCategoryChildren(rootRecordCategory.getId(),"include=isRecordCategory,isRecordFolder");
// Check status code
assertStatusCode(OK);
logger.info("Parent: " + rootRecordCategory.getId());
// Check listed children against created list
recordCategoryChildren.getEntries().forEach(c ->
{
RecordCategoryChild recordCategoryChild = c.getEntry();
String recordCategoryChildId = recordCategoryChild.getId();
assertNotNull(recordCategoryChildId);
logger.info("Checking child " + recordCategoryChildId);
try
{
// Find this child in created children list
RecordCategoryChild createdComponent = children.stream()
.filter(child -> child.getId().equals(recordCategoryChildId))
.findFirst()
.get();
// Created by
assertEquals(recordCategoryChild.getCreatedByUser().getId(), getAdminUser().getUsername());
// Is parent id set correctly?
assertEquals(recordCategoryChild.getParentId(), rootRecordCategory.getId());
// Boolean properties related to node type
// Only RECORD_CATEGORY_TYPE and RECORD_FOLDER_TYPE have been created
if (recordCategoryChild.getNodeType().equals(RECORD_CATEGORY_TYPE))
{
assertTrue(recordCategoryChild.getIsRecordCategory());
assertFalse(recordCategoryChild.getIsRecordFolder());
}
else
{
assertTrue(recordCategoryChild.getIsRecordFolder());
assertFalse(recordCategoryChild.getIsRecordCategory());
}
// Does returned object have the same contents as the created one?
assertEquals(createdComponent.getName(), recordCategoryChild.getName());
assertEquals(createdComponent.getNodeType(), recordCategoryChild.getNodeType());
// FIXME: Verify properties
assertNotNull(createdComponent.getProperties().getIdentifier());
}
catch (NoSuchElementException e)
{
fail("No child element for " + recordCategoryChildId);
}
});
}
/**
* <pre>
* Given that a record category exists
* When I ask to create an object type which is not a record category or a record folder as a child
* Then the children are not created and the 422 response code is returned
* </pre>
*/
@Test
(
description = "Create node types not allowed inside a category",
dataProviderClass = TestData.class,
dataProvider = "childrenNotAllowedForCategory"
)
@Bug (id="RM-4367, RM-4572")
public void createTypesNotAllowedInCategory(String nodeType) throws Exception
{
String componentName = "Component" + getRandomAlphanumeric();
// Create the category
RecordCategory rootRecordCategory = createRootCategory(componentName);
// Create the invalid node type
createRecordCategoryChild(rootRecordCategory.getId(), componentName, nodeType);
assertStatusCode(UNPROCESSABLE_ENTITY);
}
}

View File

@@ -26,43 +26,51 @@
*/
package org.alfresco.rest.rm.community.fileplancomponents;
import static org.alfresco.rest.rm.community.base.TestData.CATEGORY_NAME;
import static org.alfresco.rest.rm.community.base.TestData.FOLDER_NAME;
import static org.alfresco.rest.rm.community.base.TestData.FOLDER_TITLE;
import static java.time.LocalDateTime.now;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_CATEGORY_NAME;
import static org.alfresco.rest.rm.community.base.TestData.RECORD_FOLDER_NAME;
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.FilePlanComponentFields.IS_CLOSED;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PATH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.TITLE_PREFIX;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.NO_CONTENT;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
import static org.testng.AssertJUnit.assertTrue;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.TestData;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentReviewPeriod;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentsCollection;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.model.common.ReviewPeriod;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildCollection;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildProperties;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderProperties;
import org.alfresco.rest.rm.community.requests.gscore.api.FilePlanAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordFolderAPI;
import org.alfresco.utility.report.Bug;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
/**
* This class contains the tests for the
* the Record Folder CRUD API
* This class contains the tests for the Record Folder CRUD API
*
* @author Rodica Sutu
* @since 2.6
@@ -70,186 +78,185 @@ import org.testng.annotations.Test;
public class RecordFolderTests extends BaseRMRestTest
{
private static final int NUMBER_OF_FOLDERS = 5;
/**
* <pre>
* Given that a record category exists
* When I use the API to create a new record folder
* Then it is created within the record category
*
* </pre>
* <pre>
* Given that a record category exists
* When I use the API to create a folder (cm:folder type)
* Then the folder is converted to rma:recordFolder within the record category
* (see RM-4572 comments)
*
* </pre>
*/
@Test
(
description = "Create a folder into a record category.",
description = "Create a record folder into a record category.",
dataProviderClass = TestData.class,
dataProvider = "folderTypes"
)
@Bug (id = "RM-4572")
public void createFolderTest(String folderType) throws Exception
{
String CATEGORY = CATEGORY_NAME + getRandomAlphanumeric();
// Authenticate with admin user
FilePlanComponent filePlanComponent = createCategory(FILE_PLAN_ALIAS, CATEGORY);
FilePlanComponent recordFolder = FilePlanComponent.builder()
.name(FOLDER_NAME)
.nodeType(folderType)
.properties(FilePlanComponentProperties.builder()
.title(FOLDER_TITLE)
.build())
.build();
RecordCategory rootRecordCategory = createRootCategory(RECORD_CATEGORY_NAME + getRandomAlphanumeric());
// Create the record folder
FilePlanComponent folder = getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(recordFolder, filePlanComponent.getId());
RecordCategoryChild recordFolder = createRecordCategoryChild(rootRecordCategory.getId(), RECORD_FOLDER_NAME, folderType);
// Assert status code
assertStatusCode(CREATED);
// Check folder has been created within the category created
assertEquals(filePlanComponent.getId(),folder.getParentId());
// Verify the returned properties for the file plan component - record folder
assertFalse(folder.getIsCategory());
assertFalse(folder.getIsFile());
assertTrue(folder.getIsRecordFolder());
// Check record folder has been created within the record category
AssertJUnit.assertEquals(rootRecordCategory.getId(), recordFolder.getParentId());
assertEquals(folder.getName(), FOLDER_NAME);
assertEquals(folder.getNodeType(), RECORD_FOLDER_TYPE);
assertEquals(folder.getCreatedByUser().getId(), getAdminUser().getUsername());
// Verify the returned values for the record folder
assertFalse(recordFolder.getIsRecordCategory());
assertTrue(recordFolder.getIsRecordFolder());
AssertJUnit.assertEquals(recordFolder.getName(), RECORD_FOLDER_NAME);
AssertJUnit.assertEquals(recordFolder.getNodeType(), RECORD_FOLDER_TYPE);
AssertJUnit.assertEquals(recordFolder.getCreatedByUser().getId(), getAdminUser().getUsername());
// Verify the returned file plan component properties
FilePlanComponentProperties folderProperties = folder.getProperties();
assertEquals(folderProperties.getTitle(), FOLDER_TITLE);
assertNotNull(folderProperties.getRmIdentifier());
// Verify the returned record folder properties
RecordCategoryChildProperties folderProperties = recordFolder.getProperties();
AssertJUnit.assertEquals(folderProperties.getTitle(), TITLE_PREFIX + RECORD_FOLDER_NAME);
assertNotNull(folderProperties.getIdentifier());
}
/**
* <pre>
* Given that RM site is created
* When I use the API to create a new record folder into transfers container/holds container/unfiled
* When I use the API to create a new record folder into transfers/holds/unfiled containers
* Then the operation fails
* </pre>
*/
@Test
(
description = "Create a folder into hold/transfers/unfiled/file plan container",
description = "Create a record folder into transfers/unfiled/file plan container",
dataProviderClass = TestData.class,
dataProvider = "getContainers"
)
@Bug(id="RM-4327")
public void createFolderIntoSpecialContainers(String filePlanComponent) throws Exception
public void createRecordFolderIntoSpecialContainers(String containerAlias) throws Exception
{
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
String componentID = filePlanComponentsAPI.getFilePlanComponent(filePlanComponent).getId();
// Build the record category properties
FilePlanComponent recordFolder = FilePlanComponent.builder()
.name(FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.properties(FilePlanComponentProperties.builder()
.title(FOLDER_TITLE)
.build())
.build();
String containerId;
if (FILE_PLAN_ALIAS.equalsIgnoreCase(containerAlias))
{
containerId = getRestAPIFactory().getFilePlansAPI().getFilePlan(containerAlias).getId();
}
else if(TRANSFERS_ALIAS.equalsIgnoreCase(containerAlias))
{
containerId = getRestAPIFactory().getTransferContainerAPI().getTransferContainer(containerAlias).getId();
}
else
{
//is unfiled container
containerId = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(containerAlias).getId();;
}
// Create a record folder
filePlanComponentsAPI.createFilePlanComponent(recordFolder, componentID);
createRecordFolder(containerId, RECORD_FOLDER_NAME);
// Check the API Response code
assertStatusCode(UNPROCESSABLE_ENTITY);
assertStatusCode(BAD_REQUEST);
}
/**
* <pre>
* Given that a record folder exists
* When I ask for the details of a record folder
* Then I am given the details of a record folder
* </pre>
*/
@Test
(
description = "Check the details returned for a record folder"
description = "Check the details of a record folder"
)
public void checkTheRecordFolderProperties() throws Exception
public void checkRecordFolderDetails() throws Exception
{
String CATEGORY = CATEGORY_NAME + getRandomAlphanumeric();
// Create a category
RecordCategory rootRecordCategory = createRootCategory(RECORD_CATEGORY_NAME + getRandomAlphanumeric());
FilePlanComponent category = createCategory(FILE_PLAN_ALIAS, CATEGORY);
FilePlanComponent folder = createFolder(category.getId(),FOLDER_NAME);
// Create a folder
RecordCategoryChild recordCategoryChild = createRecordFolder(rootRecordCategory.getId(), RECORD_FOLDER_NAME);
FilePlanComponent folderDetails = getRestAPIFactory().getFilePlanComponentsAPI().getFilePlanComponent(folder.getId(), "include=" + IS_CLOSED);
// Get the folder including extra information
RecordFolder recordFolder = getRestAPIFactory().getRecordFolderAPI().getRecordFolder(recordCategoryChild.getId(), "include=" + IS_CLOSED);
// Verify the returned properties for the file plan component - record folder
assertEquals(RECORD_FOLDER_TYPE, folderDetails.getNodeType());
assertTrue(folderDetails.getIsRecordFolder());
assertFalse(folderDetails.getIsCategory());
assertFalse(folderDetails.getIsFile());
assertFalse(folderDetails.getIsClosed());
assertEquals(FOLDER_NAME,folderDetails.getName());
assertEquals(getAdminUser().getUsername(),folderDetails.getCreatedByUser().getId());
assertEquals(getAdminUser().getUsername(), folderDetails.getModifiedByUser().getId());
assertEquals(FOLDER_TITLE,folderDetails.getProperties().getTitle());
// Verify the returned record folder details
AssertJUnit.assertEquals(recordFolder.getNodeType(), RECORD_FOLDER_TYPE);
assertTrue(RECORD_FOLDER_TYPE.equals(recordFolder.getNodeType()));
AssertJUnit.assertEquals(recordFolder.getName(), RECORD_FOLDER_NAME);
AssertJUnit.assertEquals(recordFolder.getCreatedByUser().getId(), getAdminUser().getUsername());
AssertJUnit.assertEquals(recordFolder.getModifiedByUser().getId(), getAdminUser().getUsername());
AssertJUnit.assertEquals(recordFolder.getProperties().getTitle(), TITLE_PREFIX + RECORD_FOLDER_NAME);
}
/**
* <pre>
* Given that a record folder exists
* When I use the API to update its details
* Then the details of the record folder are updated
* The above test does treat any custom metadata
* Note: the details of the record folder includes any custom meta-data
* The above test does treat any custom metadata
* Note: The details of the record folder includes any custom meta-data
* </pre>
*/
@Test
(
description = "Update the details returned for a record folder"
description = "Update the details of a record folder"
)
public void updateTheRecordFolderProperties() throws Exception
public void updateRecordFolderDetails() throws Exception
{
String CATEGORY = CATEGORY_NAME + getRandomAlphanumeric();
// Create a record category
RecordCategory rootRecordCategory = createRootCategory(RECORD_CATEGORY_NAME + getRandomAlphanumeric());
//Create a record category
FilePlanComponent category = createCategory(FILE_PLAN_ALIAS, CATEGORY);
//Create a record folder
FilePlanComponent folder = createFolder(category.getId(), FOLDER_NAME);
// Create a record folder
RecordCategoryChild recordCategoryChild = createRecordFolder(rootRecordCategory.getId(), RECORD_FOLDER_NAME);
// Create record category first
String folderDescription = "The folder description is updated" + getRandomAlphanumeric();
String folderName = "The folder name is updated" + getRandomAlphanumeric();
String folderTitle = "Update title " + getRandomAlphanumeric();
String location = "Location"+getRandomAlphanumeric();
String location = "Location "+ getRandomAlphanumeric();
//Create the file plan component properties to update
FilePlanComponent recordFolder = FilePlanComponent.builder()
.name(folderName)
.properties(FilePlanComponentProperties.builder()
.title(folderTitle)
.description(folderDescription)
.vitalRecord(true)
.reviewPeriod(new FilePlanComponentReviewPeriod("month","1"))
.location(location)
.build())
.build();
// Create the record folder properties to update
RecordFolder recordFolder = RecordFolder.builder()
.name(folderName)
.properties(RecordFolderProperties.builder()
.title(folderTitle)
.description(folderDescription)
.vitalRecordIndicator(true)
.reviewPeriod(new ReviewPeriod("month","1"))
.location(location)
.build())
.build();
// Update the record category
FilePlanComponent folderUpdated = getRestAPIFactory().getFilePlanComponentsAPI().updateFilePlanComponent(recordFolder, folder.getId());
// Update the record folder
RecordFolder updatedRecordFolder = getRestAPIFactory().getRecordFolderAPI().updateRecordFolder(recordFolder, recordCategoryChild.getId());
// Check the Response Status Code
assertStatusCode(OK);
// Verify the returned properties for the file plan component - record folder
assertEquals(folderName, folderUpdated.getName());
assertEquals(folderDescription, folderUpdated.getProperties().getDescription());
assertEquals(folderTitle, folderUpdated.getProperties().getTitle());
assertTrue(folderUpdated.getProperties().getVitalRecord());
assertEquals(location, folderUpdated.getProperties().getLocation());
assertNotNull(folderUpdated.getProperties().getReviewPeriod().getPeriodType());
assertNotNull(folderUpdated.getProperties().getReviewPeriod().getExpression());
// Verify the returned details for the record folder
AssertJUnit.assertEquals(updatedRecordFolder.getName(), folderName);
RecordFolderProperties recordFolderProperties = updatedRecordFolder.getProperties();
AssertJUnit.assertEquals(recordFolderProperties.getDescription(), folderDescription);
AssertJUnit.assertEquals(recordFolderProperties.getTitle(), folderTitle);
assertTrue(recordFolderProperties.getVitalRecordIndicator());
AssertJUnit.assertEquals(recordFolderProperties.getLocation(), location);
assertNotNull(recordFolderProperties.getReviewPeriod().getPeriodType());
assertNotNull(recordFolderProperties.getReviewPeriod().getExpression());
}
/**
* <pre>
* Given that a record folder exists
* When I use the API to delete the record folder
* Then it deleted according to the normal rules governing the deletion of record folders
* Then it is deleted according to the normal rules governing the deletion of record folders
* </pre>
*/
@Test
(
@@ -257,95 +264,93 @@ public class RecordFolderTests extends BaseRMRestTest
)
public void deleteRecordFolder() throws Exception
{
String CATEGORY = CATEGORY_NAME + getRandomAlphanumeric();
// Create the record category
FilePlanComponent category = createCategory(FILE_PLAN_ALIAS, CATEGORY);
RecordCategory rootRecordCategory = createRootCategory(RECORD_CATEGORY_NAME + getRandomAlphanumeric());
// Create the record folder
FilePlanComponent folder = createFolder(category.getId(), FOLDER_NAME);
RecordCategoryChild recordFolder = createRecordFolder(rootRecordCategory.getId(), RECORD_FOLDER_NAME);
// Delete the Record folder
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
filePlanComponentsAPI.deleteFilePlanComponent(folder.getId());
// Check the Response Status Code
// Delete the record folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
String recordFolderId = recordFolder.getId();
recordFolderAPI.deleteRecordFolder(recordFolderId);
// Check the response status code
assertStatusCode(NO_CONTENT);
// Check the File Plan Component is not found
filePlanComponentsAPI.getFilePlanComponent(folder.getId());
// Check the Response Status Code
// Check the record folder is not found
recordFolderAPI.getRecordFolder(recordFolderId);
// Check the response status code
assertStatusCode(NOT_FOUND);
}
/**
* <pre>
* Given that a record category exists
* And contains several record folders
* When I use the APi to get the file plan component children for the existing category
* Then I am provided with a list of the contained record folders
* And their details
* When I use the API to get the record category children for an existing record category
* Then I am provided with a list of the contained record category children and their details
* </pre>
*/
@Test
(
description = "List children of a category"
description = "Get children of a record category"
)
public void listFolders() throws Exception
public void getFolders() throws Exception
{
String CATEGORY = CATEGORY_NAME + getRandomAlphanumeric();
// Authenticate with admin user
FilePlanComponent category = createCategory(FILE_PLAN_ALIAS, CATEGORY);
RecordCategory rootRecordCategory = createRootCategory(RECORD_CATEGORY_NAME + getRandomAlphanumeric());
// Add child olders
ArrayList<FilePlanComponent> children = new ArrayList<FilePlanComponent>();
// Add child folders
ArrayList<RecordCategoryChild> children = new ArrayList<RecordCategoryChild>();
for (int i = 0; i < NUMBER_OF_FOLDERS; i++)
{
// Create a child
FilePlanComponent child = createFolder(category.getId(),
getRandomAlphanumeric());
assertNotNull(child.getId());
children.add(child);
// Create a record folder
RecordCategoryChild recordCategoryChild = createRecordFolder(rootRecordCategory.getId(), getRandomAlphanumeric());
assertNotNull(recordCategoryChild.getId());
children.add(recordCategoryChild);
}
// List children from API
FilePlanComponentsCollection apiChildren = getRestAPIFactory().getFilePlanComponentsAPI().listChildComponents(category.getId());
// Get record category children from API
RecordCategoryChildCollection recordCategoryChildren = getRestAPIFactory().getRecordCategoryAPI().getRecordCategoryChildren(rootRecordCategory.getId(), "include=isRecordCategory,isRecordFolder");
// Check status code
assertStatusCode(OK);
// Check listed children against created list
apiChildren.getEntries().forEach(c ->
// Check children against created list
recordCategoryChildren.getEntries().forEach(c ->
{
FilePlanComponent filePlanComponent = c.getFilePlanComponentModel();
assertNotNull(filePlanComponent.getId());
logger.info("Checking child " + filePlanComponent.getId());
RecordCategoryChild recordCategoryChild = c.getEntry();
String recordCategoryChildId = recordCategoryChild.getId();
assertNotNull(recordCategoryChildId);
logger.info("Checking child " + recordCategoryChildId);
try
{
// Find this child in created children list
FilePlanComponent createdComponent = children.stream()
.filter(child -> child.getId().equals(filePlanComponent.getId()))
RecordCategoryChild createdComponent = children.stream()
.filter(child -> child.getId().equals(recordCategoryChildId))
.findFirst()
.get();
// Created by
assertEquals(filePlanComponent.getCreatedByUser().getId(), getAdminUser().getUsername());
assertEquals(recordCategoryChild.getCreatedByUser().getId(), getAdminUser().getUsername());
// Is parent Id set correctly
assertEquals(filePlanComponent.getParentId(), category.getId());
assertFalse(filePlanComponent.getIsFile());
// Is parent id set correctly
assertEquals(recordCategoryChild.getParentId(), rootRecordCategory.getId());
// Boolean properties related to node type
assertTrue(filePlanComponent.getIsRecordFolder());
assertFalse(filePlanComponent.getIsCategory());
assertTrue(recordCategoryChild.getIsRecordFolder());
assertFalse(recordCategoryChild.getIsRecordCategory());
assertEquals(createdComponent.getName(), filePlanComponent.getName());
assertEquals(createdComponent.getNodeType(), filePlanComponent.getNodeType());
assertEquals(createdComponent.getName(), recordCategoryChild.getName());
assertEquals(createdComponent.getNodeType(), recordCategoryChild.getNodeType());
}
catch (NoSuchElementException e)
{
fail("No child element for " + filePlanComponent.getId());
fail("No child element for " + recordCategoryChildId);
}
}
);
@@ -353,92 +358,107 @@ public class RecordFolderTests extends BaseRMRestTest
}
/**
* <pre>
* Given that I want to create a record folder
* When I use the API with the relativePath
* Then the categories specified in the relativePath that don't exist are created within the record folder
*
* Containers in the relativePath that do not exist are created before the node is created
* Then the categories specified in the relativePath that don't exist are created
* </pre>
*/
@Test
(
description = "Create a folder based on the relativePath. " +
description = "Create a folder using record-categories endpoint, based on the relativePath. " +
"Containers in the relativePath that do not exist are created before the node is created"
)
public void createFolderWithRelativePath() throws Exception
public void createRecordFolderWithRelativePath() throws Exception
{
//RelativePath specify the container structure to create relative to the record folder to be created
String relativePath = LocalDateTime.now().getYear() + "/" + LocalDateTime.now().getMonth() + "/" + LocalDateTime.now().getDayOfMonth();
// The record category to be created
RecordCategory recordCategoryModel = RecordCategory.builder()
.name(RECORD_CATEGORY_NAME)
.nodeType(RECORD_CATEGORY_TYPE)
.build();
FilePlanAPI filePlansAPI = getRestAPIFactory().getFilePlansAPI();
RecordCategory createRootRecordCategory = filePlansAPI.createRootRecordCategory(recordCategoryModel, FILE_PLAN_ALIAS, "include=" + PATH);
// Check the API response code
assertStatusCode(CREATED);
String recordCategoryId = createRootRecordCategory.getId();
//The record folder to be created
FilePlanComponent recordFolder = FilePlanComponent.builder()
.name(FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(relativePath)
.build();
// relativePath specify the container structure to create relative to the record folder to be created
String relativePath = now().getYear() + "/" + now().getMonth() + "/" + now().getDayOfMonth();
// The record folder to be created
RecordCategoryChild recordFolderModel = RecordCategoryChild.builder()
.name(RECORD_FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(relativePath)
.build();
// Create the record folder
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent folder = filePlanComponentsAPI.createFilePlanComponent(recordFolder, FILE_PLAN_ALIAS, "include=" + PATH);
//Check the API response code
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
RecordCategoryChild recordCategoryChild = recordCategoryAPI.createRecordCategoryChild(recordFolderModel, recordCategoryId, "include=" + PATH);
// Check the API response code
assertStatusCode(CREATED);
// Verify the returned properties for the file plan component - record folder
assertFalse(folder.getIsCategory());
assertFalse(folder.getIsFile());
assertTrue(folder.getIsRecordFolder());
// Verify the returned details for the record folder
assertFalse(recordCategoryChild.getIsRecordCategory());
assertTrue(recordCategoryChild.getIsRecordFolder());
//Check the path return contains the RELATIVE_PATH
assertTrue(folder.getPath().getName().contains(relativePath));
//check the parent is a category
assertTrue(filePlanComponentsAPI.getFilePlanComponent(folder.getParentId()).getIsCategory());
// Check the path return contains the relativePath
AssertJUnit.assertTrue(recordCategoryChild.getPath().getName().contains(relativePath));
//check the created folder from the server
folder = filePlanComponentsAPI.getFilePlanComponent(folder.getId(), "include=" + PATH);
//Check the API response code
// Check the parent is a category
assertNotNull(recordCategoryAPI.getRecordCategory(recordCategoryChild.getParentId()).getId());
// Check the created folder from the server
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
RecordFolder recordFolder = recordFolderAPI.getRecordFolder(recordCategoryChild.getId(), "include=" + PATH);
// Check the API response code
assertStatusCode(OK);
// Verify the returned properties for the file plan component - record folder
assertFalse(folder.getIsCategory());
assertFalse(folder.getIsFile());
assertTrue(folder.getIsRecordFolder());
//Check the path return contains the RELATIVE_PATH
assertTrue(folder.getPath().getName().contains(relativePath));
// Verify the returned details for the record folder
assertTrue(RECORD_FOLDER_TYPE.equals(recordFolder.getNodeType()));
//New Relative Path only a part of containers need to be created before the record folder
String NEW_RELATIVE_PATH = LocalDateTime.now().getYear() + "/" + LocalDateTime.now().getMonth() + "/" + (LocalDateTime.now().getDayOfMonth() + 1);
//The record folder to be created
FilePlanComponent recordFolder2 = FilePlanComponent.builder()
.name(FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(NEW_RELATIVE_PATH)
.build();
// Check the path return contains the relativePath
AssertJUnit.assertTrue(recordFolder.getPath().getName().contains(relativePath));
// New relative path only a part of containers need to be created before the record folder
String newRelativePath = now().getYear() + "/" + now().getMonth() + "/" + (now().getDayOfMonth() + 1);
// The record folder to be created
RecordCategoryChild newRecordFolderModel = RecordCategoryChild.builder()
.name(RECORD_FOLDER_NAME)
.nodeType(RECORD_FOLDER_TYPE)
.relativePath(newRelativePath)
.build();
// Create the record folder
FilePlanComponent folder2 = filePlanComponentsAPI.createFilePlanComponent(recordFolder2, FILE_PLAN_ALIAS, "include=" + PATH);
//Check the API response code
RecordCategoryChild newRecordCategoryChild = recordCategoryAPI.createRecordCategoryChild(newRecordFolderModel, recordCategoryId, "include=" + PATH);
// Check the API response code
assertStatusCode(CREATED);
// Verify the returned properties for the file plan component - record folder
assertFalse(folder2.getIsCategory());
assertFalse(folder2.getIsFile());
assertTrue(folder2.getIsRecordFolder());
//Check the path return contains the NEW_RELATIVE_PATH
assertTrue(folder2.getPath().getName().contains(NEW_RELATIVE_PATH));
assertFalse(newRecordCategoryChild.getIsRecordCategory());
assertTrue(newRecordCategoryChild.getIsRecordFolder());
//check the parent is a category
assertTrue(filePlanComponentsAPI.getFilePlanComponent(folder.getParentId()).getIsCategory());
// Check the path return contains the newRelativePath
AssertJUnit.assertTrue(newRecordCategoryChild.getPath().getName().contains(newRelativePath));
// Check the parent is a category
assertNotNull(recordCategoryAPI.getRecordCategory(newRecordCategoryChild.getParentId()).getId());
// Check the folder created on the server
folder2 = filePlanComponentsAPI.getFilePlanComponent(folder2.getId(), "include=" + PATH);
//Check the API response code
RecordFolder newRecordFolder = recordFolderAPI.getRecordFolder(newRecordCategoryChild.getId(), "include=" + PATH);
// Check the API response code
assertStatusCode(OK);
// Verify the returned properties for the file plan component - record folder
assertFalse(folder2.getIsCategory());
assertFalse(folder2.getIsFile());
assertTrue(folder2.getIsRecordFolder());
//Check the path return contains the NEW_RELATIVE_PATH
assertTrue(folder2.getPath().getName().contains(NEW_RELATIVE_PATH));
// Verify the returned details for the record folder
assertTrue(RECORD_FOLDER_TYPE.equals(recordFolder.getNodeType()));
// Check the path return contains the newRelativePath
AssertJUnit.assertTrue(newRecordFolder.getPath().getName().contains(newRelativePath));
}
/**
@@ -454,55 +474,57 @@ public class RecordFolderTests extends BaseRMRestTest
public void openClosedRecordFolder() throws Exception
{
// Create a record folder
FilePlanComponent recordFolder = createCategoryFolderInFilePlan();
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
// Assert that the record folder is not closed
assertFalse(recordFolder.getProperties().getIsClosed());
// Get the file plan component API
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
// Get the record folder API
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
// Create a record folder model to close it
FilePlanComponent recordFolderModel = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.isClosed(true)
.build())
.build();
RecordFolder recordFolderModel = RecordFolder.builder()
.properties(RecordFolderProperties.builder()
.isClosed(true)
.build())
.build();
// Make a request to close the record folder
FilePlanComponent updatedRecordFolder = filePlanComponentsAPI.updateFilePlanComponent(recordFolderModel, recordFolder.getId());
RecordFolder updatedRecordFolder = recordFolderAPI.updateRecordFolder(recordFolderModel, recordFolder.getId());
//FIXME - remove this workaround after RM-4921 is fixed.
updatedRecordFolder = recordFolderAPI.getRecordFolder(updatedRecordFolder.getId());
// Verify that the record folder is closed now
assertTrue(updatedRecordFolder.getProperties().getIsClosed());
// Create a record folder model to reopen it
recordFolderModel = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
.isClosed(false)
.build())
.build();
recordFolderModel = RecordFolder.builder()
.properties(RecordFolderProperties.builder()
.isClosed(false)
.build())
.build();
// Make a request to reopen the record folder
updatedRecordFolder = filePlanComponentsAPI.updateFilePlanComponent(recordFolderModel, recordFolder.getId());
updatedRecordFolder = recordFolderAPI.updateRecordFolder(recordFolderModel, recordFolder.getId());
//FIXME - remove this workaround after RM-4921 is fixed.
updatedRecordFolder = recordFolderAPI.getRecordFolder(updatedRecordFolder.getId());
// Verify that the record folder is open now
assertFalse(updatedRecordFolder.getProperties().getIsClosed());
}
@AfterMethod
@AfterClass (alwaysRun = true)
public void tearDown() throws Exception
{
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
filePlanComponentsAPI.listChildComponents(FILE_PLAN_ALIAS).getEntries().forEach(filePlanComponentEntry ->
FilePlanAPI filePlansAPI = getRestAPIFactory().getFilePlansAPI();
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
filePlansAPI.getRootRecordCategories(FILE_PLAN_ALIAS).getEntries().forEach(recordCategoryEntry ->
{
try
{
filePlanComponentsAPI.deleteFilePlanComponent(filePlanComponentEntry.getFilePlanComponentModel().getId());
}
catch (Exception e)
{
e.printStackTrace();
}
recordCategoryAPI.deleteRecordCategory(recordCategoryEntry.getEntry().getId());
});
}
}

View File

@@ -0,0 +1,353 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.fileplancomponents;
import static java.time.LocalDateTime.now;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
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_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplan.FilePlan;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainer;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildCollection;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
/**
* Unfiled container related API tests
*
* @author Ana Bozianu
* @since 2.6
*/
public class UnfiledContainerTests extends BaseRMRestTest
{
/** Number of children (for children creation test) */
private static final int NUMBER_OF_CHILDREN = 10;
/**
* <pre>
* Given the RM site exists
* When I retrieve the unfiled record conteiner by placeholder
* Then the details of the unfiled record container is returned
* </pre>
*/
@Test
(
description = "Get the unfiled records container"
)
public void getUnfiledRecordsContainer() throws Exception
{
// Get the unfiled records container
UnfiledContainer container = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS);
// Check the response code
assertStatusCode(OK);
// Check the response contains the right node type
assertEquals(container.getNodeType(), UNFILED_CONTAINER_TYPE);
}
/**
* <pre>
* Given that an unfiled container exists
* When I ask the API to update the details of the unfiled container
* Then the details of the unfiled container are updated
* </pre>
*/
@Test
(
description = "Rename unfiled container"
)
public void renameUnfiledContainer() throws Exception
{
String newContainerName = "RenamedUnfiledContainer (" + getRandomAlphanumeric() + ")";
// Build the properties which will be updated
UnfiledContainer unfiledContainerUpdate = UnfiledContainer.builder().name(newContainerName).build();
// Update the unfiled records container
UnfiledContainer renamedUnfiledContainer = getRestAPIFactory().getUnfiledContainersAPI().updateUnfiledContainer(unfiledContainerUpdate, UNFILED_RECORDS_CONTAINER_ALIAS);
// Verify the status code
assertStatusCode(OK);
// Verify the returned unfiled records container
assertEquals(renamedUnfiledContainer.getName(), newContainerName);
// Get actual FILE_PLAN_ALIAS id
FilePlan filePlan = getRestAPIFactory().getFilePlansAPI().getFilePlan(FILE_PLAN_ALIAS);
// verify renamed component still has this parent
assertEquals(renamedUnfiledContainer.getParentId(), filePlan.getId());
}
/**
* <pre>
* Given that an unfiled records container exists
* When I ask the API to create a child unfiled record folder
* Then it is created within the unfiled records container
* </pre>
*/
@Test
(
description = "Create unfiled record folder child in unfiled root container"
)
public void createUnfiledRecordFolderChild() throws Exception
{
String unfiledRecordFolderName = "UnfiledRecordFolder-" + getRandomAlphanumeric();
UnfiledContainerChild unfiledRecordFolder = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, unfiledRecordFolderName, UNFILED_RECORD_FOLDER_TYPE);
assertNotNull(unfiledRecordFolder.getId());
UnfiledContainer container = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS);
assertEquals(unfiledRecordFolder.getParentId(), container.getId());
assertFalse(unfiledRecordFolder.getIsRecord());
assertEquals(unfiledRecordFolder.getNodeType(), UNFILED_RECORD_FOLDER_TYPE);
}
/**
* <pre>
* Given that an unfiled records container exists
* When I ask the API to create a child unfiled record folder with relative path
* Then it is not supported
* </pre>
*/
@Test
(
description = "Create unfiled record folder child in unfiled root container"
)
public void createUnfiledRecordFolderChildWithRealtivePathNotSuported() throws Exception
{
UnfiledContainerAPI unfiledContainerAPI = getRestAPIFactory().getUnfiledContainersAPI();
// relativePath specify the container structure to create relative to
// the record folder to be created
String relativePath = now().getYear() + "/" + now().getMonth() + "/" + now().getDayOfMonth();
String unfiledRecordFolderName = "UnfiledRecordFolder-" + getRandomAlphanumeric();
UnfiledContainerChild unfiledFolderModel = UnfiledContainerChild.builder()
.name(unfiledRecordFolderName)
.nodeType(UNFILED_RECORD_FOLDER_TYPE)
.relativePath(relativePath)
.build();
unfiledContainerAPI.createUnfiledContainerChild(unfiledFolderModel, UNFILED_RECORDS_CONTAINER_ALIAS);
// Check the API response code
assertStatusCode(BAD_REQUEST);
}
/**
* <pre>
* Given that an unfiled records container exists
* When I ask the API to create a child record
* Then it is created within the unfiled records container
* </pre>
*/
@Test
(
description = "Create record child in unfiled root container"
)
public void createNonElectronicRecordChild() throws Exception
{
String recordName = "NERecord-" + getRandomAlphanumeric();
UnfiledContainerChild unfiledRecord = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, recordName, NON_ELECTRONIC_RECORD_TYPE);
assertNotNull(unfiledRecord.getId());
assertTrue(unfiledRecord.getIsRecord());
assertEquals(unfiledRecord.getNodeType(), NON_ELECTRONIC_RECORD_TYPE);
// check it was created in the unfiled root container
UnfiledContainer container = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS);
assertEquals(unfiledRecord.getParentId(), container.getId());
// check the name contains the identifier
String identifier = unfiledRecord.getProperties().getIdentifier();
assertNotNull(identifier);
assertEquals(unfiledRecord.getName(), recordName + " (" + identifier + ")");
}
/**
* <pre>
* Given that an unfiled records container exists
* When I ask the API to create a child record
* Then it is created within the unfiled records container
* </pre>
*/
@Test
(
description = "Create electronic record child in unfiled root container"
)
public void createElectronicRecordChild() throws Exception
{
String recordName = "ERecord-" + getRandomAlphanumeric();
UnfiledContainerChild unfiledRecord = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, recordName, CONTENT_TYPE);
assertNotNull(unfiledRecord.getId());
assertTrue(unfiledRecord.getIsRecord());
assertEquals(unfiledRecord.getNodeType(), CONTENT_TYPE);
// check it was created in the unfiled root container
UnfiledContainer container = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS);
assertEquals(unfiledRecord.getParentId(), container.getId());
// check the name contains the identifier
String identifier = unfiledRecord.getProperties().getIdentifier();
assertNotNull(identifier);
assertEquals(unfiledRecord.getName(), recordName + " (" + identifier + ")");
}
/**
* <pre>
* Given the RM site is created
* And contains a number of records and unfiled record folders
* When I ask the API to get me the children of the unfiled root container
* Then I am returned the contained record and unfiled record folders
* </pre>
*/
@Test
(
description = "Get children of the root unfiled root container"
)
public void getUnfiledRootContainerChildren() throws Exception
{
// Add unfiled root container children
List<UnfiledContainerChild> createdChildren = new LinkedList<>();
for (int i=0; i < NUMBER_OF_CHILDREN; i++)
{
String childType;
if (i % 3 == 0)
{
childType = CONTENT_TYPE;
}
else if (i % 3 == 1)
{
childType = NON_ELECTRONIC_RECORD_TYPE;
}
else
{
childType = UNFILED_RECORD_FOLDER_TYPE;
}
UnfiledContainerChild child = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, getRandomAlphanumeric(), childType);
assertNotNull(child.getId());
createdChildren.add(child);
}
// Get children from API
UnfiledContainerChildCollection listedChildren = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS);
// Check status code
assertStatusCode(OK);
// Check listed children contains created list
UnfiledContainer unfiledContainer = getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS);
List<UnfiledContainerChild> verifiedChildren = new LinkedList<>();
listedChildren.getEntries().forEach(c ->
{
UnfiledContainerChild containerChild = c.getEntry();
String childId = containerChild.getId();
assertNotNull(childId);
logger.info("Checking child " + childId);
try
{
// Get the element from the created children list
UnfiledContainerChild createdComponent = createdChildren.stream()
.filter(child -> child.getId().equals(childId))
.findFirst()
.get();
// Created by
assertEquals(containerChild.getCreatedByUser().getId(), getAdminUser().getUsername());
// Is parent id set correctly?
assertEquals(containerChild.getParentId(), unfiledContainer.getId());
// Boolean properties related to node type
if (containerChild.getNodeType().equals(UNFILED_RECORD_FOLDER_TYPE))
{
assertFalse(containerChild.getIsRecord());
}
else
{
assertTrue(containerChild.getIsRecord());
}
// Does returned object have the same contents as the created one?
assertEquals(createdComponent.getName(), containerChild.getName());
assertEquals(createdComponent.getNodeType(), containerChild.getNodeType());
// FIXME: Verify properties
assertNotNull(createdComponent.getProperties().getIdentifier());
// add the element to the matched children list
verifiedChildren.add(createdComponent);
}
catch (NoSuchElementException e)
{
// the element was not created in this test, continue
}
});
// check all the created elements have been returned
assertTrue(verifiedChildren.containsAll(createdChildren));
assertTrue(createdChildren.containsAll(verifiedChildren));
}
@AfterMethod
@AfterClass (alwaysRun = true)
public void tearDown() throws Exception
{
UnfiledContainerChildCollection listedChildren = getRestAPIFactory().getUnfiledContainersAPI()
.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS);
listedChildren.getEntries().forEach(UnfiledContainerChildEntry ->
{
if (UnfiledContainerChildEntry.getEntry().getIsRecord())
{
getRestAPIFactory().getRecordsAPI().deleteRecord(UnfiledContainerChildEntry.getEntry().getId());
}
else
{
getRestAPIFactory().getUnfiledRecordFoldersAPI().deleteUnfiledRecordFolder(UnfiledContainerChildEntry.getEntry().getId());
}
});
}
}

View File

@@ -26,15 +26,18 @@
*/
package org.alfresco.rest.rm.community.fileplancomponents;
import static java.time.LocalDateTime.now;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentFields.PATH;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.CONTENT_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.FILE_PLAN_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.HOLD_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.HOLD_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.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.TRANSFER_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_CONTAINER_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createUnfiledContainerChildModel;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.NOT_FOUND;
@@ -43,16 +46,20 @@ import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.List;
import java.util.stream.Collectors;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentsCollection;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildCollection;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildProperties;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledRecordFolder;
import org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -67,15 +74,13 @@ public class UnfiledRecordsFolderTests extends BaseRMRestTest
/** invalid root level types, at unfiled records root level these shouldn't be possible to create */
@DataProvider(name = "invalidRootTypes")
public Object[][] createData1()
public String[][] createData()
{
return new Object[][]
return new String[][]
{
{ FILE_PLAN_TYPE },
{ RECORD_CATEGORY_TYPE },
{ RECORD_FOLDER_TYPE },
{ HOLD_TYPE },
{ HOLD_CONTAINER_TYPE },
{ TRANSFER_CONTAINER_TYPE },
{ UNFILED_CONTAINER_TYPE }
};
@@ -91,70 +96,140 @@ public class UnfiledRecordsFolderTests extends BaseRMRestTest
@Test(description = "Create root unfiled records folder")
public void createRootUnfiledRecordsFolder() throws Exception
{
String folderName = "Folder " + getRandomAlphanumeric();
String folderTitle = folderName + " Title";
String folderDescription = folderName + " Description";
String unfiledRecordFolderName = "UnfiledRecordFolder-" + getRandomAlphanumeric();
UnfiledContainerChild unfiledRecordFolderChild = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, unfiledRecordFolderName, UNFILED_RECORD_FOLDER_TYPE);
// Build unfiled records folder properties
FilePlanComponent unfiledFolder = FilePlanComponent.builder()
.name(folderName)
.nodeType(UNFILED_RECORD_FOLDER_TYPE)
.properties(FilePlanComponentProperties.builder()
.title(folderTitle)
.description(folderDescription)
.build())
.build();
FilePlanComponent filePlanComponent = getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(unfiledFolder, UNFILED_RECORDS_CONTAINER_ALIAS);
// Verify the status code
assertStatusCode(CREATED);
assertNotNull(unfiledRecordFolderChild.getId());
// Verify the returned file plan component
assertFalse(filePlanComponent.getIsCategory());
assertFalse(filePlanComponent.getIsFile());
assertFalse(filePlanComponent.getIsRecordFolder()); // it is not a _normal_ record folder!
assertFalse(unfiledRecordFolderChild.getIsRecord());
assertTrue(unfiledRecordFolderChild.getIsUnfiledRecordFolder()); // it is not a _normal_ record folder!
assertEquals(filePlanComponent.getName(), folderName);
assertEquals(filePlanComponent.getNodeType(), UNFILED_RECORD_FOLDER_TYPE);
assertEquals(unfiledRecordFolderChild.getName(), unfiledRecordFolderName);
assertEquals(unfiledRecordFolderChild.getNodeType(), UNFILED_RECORD_FOLDER_TYPE);
assertEquals(filePlanComponent.getCreatedByUser().getId(), getAdminUser().getUsername());
assertEquals(unfiledRecordFolderChild.getCreatedByUser().getId(), getAdminUser().getUsername());
UnfiledRecordFolder unfiledRecordFolder = getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(unfiledRecordFolderChild.getId());
// Verify the returned file plan component properties
FilePlanComponentProperties filePlanComponentProperties = filePlanComponent.getProperties();
assertEquals(filePlanComponentProperties.getTitle(), folderTitle);
assertEquals(filePlanComponentProperties.getDescription(), folderDescription);
UnfiledContainerChildProperties unfiledRecordFolderChildProperties = unfiledRecordFolder.getProperties();
assertEquals(unfiledRecordFolderChildProperties.getTitle(), FilePlanComponentsUtil.TITLE_PREFIX + unfiledRecordFolderName);
}
/**
* <pre>
* Given that I want to create an unfiled record folder
* When I use the API with the relativePath
* Then the folders specified in the relativePath that don't exist are created
* </pre>
*/
@Test
(
description = "Create a folder based on the relativePath. " +
"Containers in the relativePath that do not exist are created before the node is created"
)
public void createUnfiledRecordFolderWithRelativePath() throws Exception
{
String unfiledRecordFolderName1 = "UnfiledRecordFolder-" + getRandomAlphanumeric();
UnfiledContainerChild unfiledRecordFolderChild1 = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, unfiledRecordFolderName1, UNFILED_RECORD_FOLDER_TYPE);
String unfiledRecordFolderName2 = "UnfiledRecordFolder-" + getRandomAlphanumeric();
// relativePath specify the container structure to create relative to the record folder to be created
String relativePath = now().getYear() + "/" + now().getMonth() + "/" + now().getDayOfMonth();
// The record folder to be created
UnfiledContainerChild unfiledFolderModel =UnfiledContainerChild.builder()
.name(unfiledRecordFolderName2)
.nodeType(UNFILED_RECORD_FOLDER_TYPE)
.relativePath(relativePath)
.build();
UnfiledContainerChild unfiledRecordFolderChild = getRestAPIFactory().getUnfiledRecordFoldersAPI().createUnfiledRecordFolderChild(unfiledFolderModel, unfiledRecordFolderChild1.getId(), "include=" + PATH);
// Check the API response code
assertStatusCode(CREATED);
// Verify the returned details for the record folder
assertFalse(unfiledRecordFolderChild.getIsRecord());
assertTrue(unfiledRecordFolderChild.getIsUnfiledRecordFolder());
assertTrue(UNFILED_RECORD_FOLDER_TYPE.equals(unfiledRecordFolderChild.getNodeType()));
// Check the path return contains the relativePath
assertTrue(unfiledRecordFolderChild.getPath().getName().contains(relativePath));
// Check the parent is a folder, not a record
assertTrue(getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(unfiledRecordFolderChild.getParentId()).getNodeType().equals(UNFILED_RECORD_FOLDER_TYPE));
// Check the created folder from the server
UnfiledRecordFolder recordFolder = getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(unfiledRecordFolderChild.getId(), "include=" + PATH);
// Check the API response code
assertStatusCode(OK);
// Check the path return contains the relativePath
assertTrue(recordFolder.getPath().getName().contains(relativePath));
// New relative path only a part of containers need to be created before the record folder
String newRelativePath = now().getYear() + "/" + now().getMonth() + "/" + (now().getDayOfMonth() + 1);
String unfiledRecordFolderName3 = "UnfiledRecordFolder-" + getRandomAlphanumeric();
// The record folder to be created
UnfiledContainerChild newUnfiledFolderModel =UnfiledContainerChild.builder()
.name(unfiledRecordFolderName3)
.nodeType(UNFILED_RECORD_FOLDER_TYPE)
.relativePath(newRelativePath)
.build();
UnfiledContainerChild newUnfiledRecordFolderChild = getRestAPIFactory().getUnfiledRecordFoldersAPI().createUnfiledRecordFolderChild(newUnfiledFolderModel, unfiledRecordFolderChild1.getId(), "include=" + PATH);
// Check the API response code
assertStatusCode(CREATED);
// Check the API response code
assertStatusCode(CREATED);
// Verify the returned properties for the unfiled record folder
assertTrue(newUnfiledRecordFolderChild.getIsUnfiledRecordFolder());
assertFalse(newUnfiledRecordFolderChild.getIsRecord());
// Check the path return contains the newRelativePath
assertTrue(newUnfiledRecordFolderChild.getPath().getName().contains(newRelativePath));
// Check the parent is a folder, not a record
assertFalse(getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(newUnfiledRecordFolderChild.getParentId()).equals(UNFILED_RECORD_FOLDER_TYPE));
// Check the folder created on the server
UnfiledRecordFolder newRecordFolder = getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(newUnfiledRecordFolderChild.getId(), "include=" + PATH);
// Check the API response code
assertStatusCode(OK);
// Check the path return contains the newRelativePath
assertTrue(newRecordFolder.getPath().getName().contains(newRelativePath));
}
/**
* Negative test to verify only unfiled record folders can be created at root level
* Negative test to check that invalid types cannot be created at unfiled container root level
* Only unfiled record folders and records can be created into unfiled container
*/
@Test
(
dataProvider = "invalidRootTypes",
description = "Only unfiled records folders can be created at unfiled records root level"
description = "Only unfiled records folders can be created at unfiled records root level"
)
public void onlyRecordFoldersCanBeCreatedAtUnfiledRecordsRoot(String filePlanComponentType)
{
String folderName = "Folder " + getRandomAlphanumeric();
String folderTitle = folderName + " Title";
String folderDescription = folderName + " Description";
String unfiledRecordFolderName = "UnfiledRecordFolder-" + getRandomAlphanumeric();
logger.info("creating " + filePlanComponentType);
// Build unfiled records folder properties
FilePlanComponent unfiledFolder = FilePlanComponent.builder()
.name(folderName)
.nodeType(filePlanComponentType)
.properties(FilePlanComponentProperties.builder()
.title(folderTitle)
.description(folderDescription)
.build())
.build();
UnfiledContainerChild unfiledFolderModel = createUnfiledContainerChildModel(unfiledRecordFolderName, filePlanComponentType);
try
{
getRestAPIFactory().getFilePlanComponentsAPI().createFilePlanComponent(unfiledFolder, UNFILED_RECORDS_CONTAINER_ALIAS);
getRestAPIFactory().getUnfiledContainersAPI().createUnfiledContainerChild(unfiledFolderModel, UNFILED_RECORDS_CONTAINER_ALIAS);
}
catch (Exception error)
{
@@ -174,60 +249,61 @@ public class UnfiledRecordsFolderTests extends BaseRMRestTest
@Test(description = "Child unfiled records folder can be created in a parent unfiled records folder")
public void childUnfiledRecordsFolderCanBeCreated() throws Exception
{
String parentFolderName = "Parent Folder " + getRandomAlphanumeric();
String childFolderName = "Child Folder " + getRandomAlphanumeric();
String childFolderTitle = childFolderName + " Title";
String childFolderDescription = childFolderName + " Description";
String unfiledParentFolderName = "UnfiledParentFolder" + getRandomAlphanumeric();
String unfiledChildFolderName = "UnfiledChildFolder " + getRandomAlphanumeric();
String rootUnfiledFolderName = "RootUnfiledFolder" + getRandomAlphanumeric();
//create root unfiled record folder
UnfiledContainerChild createUnfiledContainerChild = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, rootUnfiledFolderName, UNFILED_RECORD_FOLDER_TYPE);
// No need for fine control, create it using utility function
FilePlanComponent parentFolder = createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS, parentFolderName);
assertEquals(parentFolderName, parentFolder.getName());
UnfiledContainerChild unfiledParentFolder = createUnfiledRecordsFolderChild(createUnfiledContainerChild.getId(),
unfiledParentFolderName, UNFILED_RECORD_FOLDER_TYPE);
assertEquals(unfiledParentFolderName, unfiledParentFolder.getName());
// Build the unfiled records folder properties
FilePlanComponent unfiledFolder = FilePlanComponent.builder()
.name(childFolderName)
UnfiledContainerChild unfiledChildFolderModel = UnfiledContainerChild.builder().name(unfiledChildFolderName)
.nodeType(UNFILED_RECORD_FOLDER_TYPE)
.properties(FilePlanComponentProperties.builder()
.title(childFolderTitle)
.description(childFolderDescription)
.build())
.properties(UnfiledContainerChildProperties.builder().title(FilePlanComponentsUtil.TITLE_PREFIX + unfiledChildFolderName)
.description(FilePlanComponentsUtil.DESCRIPTION_PREFIX + unfiledChildFolderName).build())
.build();
// Create it as a child of parentFolder
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent childFolder = filePlanComponentsAPI.createFilePlanComponent(unfiledFolder, parentFolder.getId());
UnfiledContainerChild unfiledChildFolder = getRestAPIFactory().getUnfiledRecordFoldersAPI()
.createUnfiledRecordFolderChild(unfiledChildFolderModel, unfiledParentFolder.getId());
// Verify the status code
assertStatusCode(CREATED);
// Verify the returned file plan component
assertFalse(childFolder.getIsCategory());
assertFalse(childFolder.getIsFile());
assertFalse(childFolder.getIsRecordFolder()); // it is not a _normal_ record folder!
// Verify the returned unfiled child folder
assertTrue(unfiledChildFolder.getIsUnfiledRecordFolder());
assertFalse(unfiledChildFolder.getIsRecord());
assertEquals(childFolder.getName(), childFolderName);
assertEquals(childFolder.getNodeType(), UNFILED_RECORD_FOLDER_TYPE);
assertEquals(childFolder.getCreatedByUser().getId(), getAdminUser().getUsername());
assertEquals(unfiledChildFolder.getName(), unfiledChildFolderName);
assertEquals(unfiledChildFolder.getNodeType(), UNFILED_RECORD_FOLDER_TYPE);
assertEquals(unfiledChildFolder.getCreatedByUser().getId(), getAdminUser().getUsername());
// Verify the returned file plan component properties
FilePlanComponentProperties childProperties = childFolder.getProperties();
assertEquals(childProperties.getTitle(), childFolderTitle);
assertEquals(childProperties.getDescription(), childFolderDescription);
UnfiledRecordFolder unfiledChildRecordFolder = getRestAPIFactory().getUnfiledRecordFoldersAPI()
.getUnfiledRecordFolder(unfiledChildFolder.getId());
// Verify the returned file plan component properties
UnfiledContainerChildProperties unfiledChildFolderProperties = unfiledChildRecordFolder.getProperties();
assertEquals(unfiledChildFolderProperties.getTitle(), FilePlanComponentsUtil.TITLE_PREFIX + unfiledChildFolderName);
assertEquals(unfiledChildFolderProperties.getDescription(), FilePlanComponentsUtil.DESCRIPTION_PREFIX + unfiledChildFolderName);
// Does this child point to its parent?
assertEquals(childFolder.getParentId(), parentFolder.getId());
assertEquals(unfiledChildFolder.getParentId(), unfiledParentFolder.getId());
// Does child's parent point to it?
// Perform another call as our parentFolder had been executed before childFolder existed
FilePlanComponentsCollection parentsChildren = filePlanComponentsAPI.listChildComponents(parentFolder.getId());
UnfiledContainerChildCollection parentsChildren = getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolderChildren(unfiledParentFolder.getId());
assertStatusCode(OK);
List<String> childIds = parentsChildren.getEntries()
.stream()
.map(c -> c.getFilePlanComponentModel().getId())
.map(c -> c.getEntry().getId())
.collect(Collectors.toList());
// Child folder is listed in parent
assertTrue(childIds.contains(childFolder.getId()));
assertTrue(childIds.contains(unfiledChildFolder.getId()));
// There should be only one child
assertEquals(1, childIds.size());
@@ -244,61 +320,96 @@ public class UnfiledRecordsFolderTests extends BaseRMRestTest
public void editUnfiledRecordsFolder() throws Exception
{
String modified = "Modified ";
String folderName = "Folder To Modify" + getRandomAlphanumeric();
String unfiledFolderName = "UnfiledFolderToModify" + getRandomAlphanumeric();
String rootUnfiledFolderName = "RootUnfiledFolder" + getRandomAlphanumeric();
//create root unfiledRecordFolder
UnfiledContainerChild createUnfiledContainerChild = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS,rootUnfiledFolderName, UNFILED_RECORD_FOLDER_TYPE);
// No need for fine control, create it using utility function
FilePlanComponent folderToModify = createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS, folderName);
assertEquals(folderName, folderToModify.getName());
UnfiledContainerChild unfiledFolderToModify = createUnfiledRecordsFolderChild(createUnfiledContainerChild.getId(),
unfiledFolderName, UNFILED_RECORD_FOLDER_TYPE);
assertEquals(unfiledFolderName, unfiledFolderToModify.getName());
// Build the properties which will be updated
FilePlanComponent folderToUpdate = FilePlanComponent.builder()
.name(modified + folderToModify.getName())
.properties(FilePlanComponentProperties.builder().
title(modified + folderToModify.getProperties().getTitle()).
description(modified + folderToModify.getProperties().getDescription())
.build())
.build();
UnfiledRecordFolder unfiledChildFolderModel = UnfiledRecordFolder.builder().name(modified + unfiledFolderName)
.properties(UnfiledContainerChildProperties.builder().title(modified + unfiledFolderToModify.getProperties().getTitle())
.description(modified + unfiledFolderToModify.getProperties().getDescription()).build())
.build();
// Update the unfiled records folder
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
filePlanComponentsAPI.updateFilePlanComponent(folderToUpdate, folderToModify.getId());
getRestAPIFactory().getUnfiledRecordFoldersAPI().updateUnfiledRecordFolder(unfiledChildFolderModel, unfiledFolderToModify.getId());
// Verify the status code
assertStatusCode(OK);
// This is to ensure the change was actually applied, rather than simply trusting the object returned by PUT
FilePlanComponent renamedFolder = filePlanComponentsAPI.getFilePlanComponent(folderToModify.getId());
UnfiledRecordFolder renamedUnfiledFolder = getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(unfiledFolderToModify.getId());
// Verify the returned file plan component
assertEquals(modified + folderToModify.getName(), renamedFolder.getName());
assertEquals(modified + folderToModify.getProperties().getTitle(), renamedFolder.getProperties().getTitle());
assertEquals(modified + folderToModify.getProperties().getDescription(), renamedFolder.getProperties().getDescription());
assertEquals(modified + unfiledFolderToModify.getName(), renamedUnfiledFolder.getName());
assertEquals(modified + unfiledFolderToModify.getProperties().getTitle(), renamedUnfiledFolder.getProperties().getTitle());
assertEquals(modified + unfiledFolderToModify.getProperties().getDescription(), renamedUnfiledFolder.getProperties().getDescription());
}
/**
* Given an unfiled record folder
* Given an unfiled record folder and some records inside
* When I delete the unfiled record folder via the ReST API
* Then the unfiled record folder is deleted
* Then the unfiled record folder is deleted and its content too
*
* @throws Exception for failed actions
*/
@Test(description = "Delete unfiled record folder")
public void deleteUnfiledRecordsFolder() throws Exception
{
String folderName = "Folder To Delete" + getRandomAlphanumeric();
String unfiledFolderName = "UnfiledFolderToDelete" + getRandomAlphanumeric();
String nonElectronicRecordName = "NonElectronicRecord" + getRandomAlphanumeric();
String electronicRecordName = "ElectronicRecord" + getRandomAlphanumeric();
String rootUnfiledFolderName = "RootUnfiledFolder" + getRandomAlphanumeric();
// Create folderToDelete
FilePlanComponent folderToDelete = createUnfiledRecordsFolder(UNFILED_RECORDS_CONTAINER_ALIAS, folderName);
assertEquals(folderName, folderToDelete.getName());
//create root unfiled record folder
UnfiledContainerChild createUnfiledContainerChild = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, rootUnfiledFolderName, UNFILED_RECORD_FOLDER_TYPE);
// Create unfiledFolderToDelete
UnfiledContainerChild unfiledFolderToDelete = createUnfiledRecordsFolderChild(createUnfiledContainerChild.getId(),
unfiledFolderName, UNFILED_RECORD_FOLDER_TYPE);
assertEquals(unfiledFolderName, unfiledFolderToDelete.getName());
// Create a non electronic record under unfiledFolderToDelete
UnfiledContainerChild nonElectronicRecord = createUnfiledRecordsFolderChild(unfiledFolderToDelete.getId(),
nonElectronicRecordName, NON_ELECTRONIC_RECORD_TYPE);
assertTrue(nonElectronicRecord.getParentId().equals(unfiledFolderToDelete.getId()));
// Create an electronic record under unfiledFolderToDelete
UnfiledContainerChild electronicRecord = createUnfiledRecordsFolderChild(unfiledFolderToDelete.getId(),
electronicRecordName, CONTENT_TYPE);
assertTrue(electronicRecord.getParentId().equals(unfiledFolderToDelete.getId()));
// Delete folderToDelete
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
filePlanComponentsAPI.deleteFilePlanComponent(folderToDelete.getId());
getRestAPIFactory().getUnfiledRecordFoldersAPI().deleteUnfiledRecordFolder(unfiledFolderToDelete.getId());
// Verify the status code
assertStatusCode(NO_CONTENT);
// Deleted component should no longer be retrievable
filePlanComponentsAPI.getFilePlanComponent(folderToDelete.getId());
getRestAPIFactory().getUnfiledRecordFoldersAPI().getUnfiledRecordFolder(unfiledFolderToDelete.getId());
assertStatusCode(NOT_FOUND);
}
@AfterMethod
@AfterClass (alwaysRun = true)
public void tearDown() throws Exception
{
UnfiledContainerChildCollection listedChildren = getRestAPIFactory().getUnfiledContainersAPI()
.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS);
listedChildren.getEntries().forEach(UnfiledContainerChildEntry ->
{
if (UnfiledContainerChildEntry.getEntry().getIsRecord())
{
getRestAPIFactory().getRecordsAPI().deleteRecord(UnfiledContainerChildEntry.getEntry().getId());
}
else
{
getRestAPIFactory().getUnfiledRecordFoldersAPI().deleteUnfiledRecordFolder(UnfiledContainerChildEntry.getEntry().getId());
}
});
}
}

View File

@@ -26,9 +26,16 @@
*/
package org.alfresco.rest.rm.community.fileplancomponents;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.IMAGE_FILE;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createElectronicUnfiledContainerChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createNonElectronicUnfiledContainerChildModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.createRecordModel;
import static org.alfresco.rest.rm.community.utils.FilePlanComponentsUtil.getFile;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.OK;
@@ -37,16 +44,22 @@ import static org.testng.Assert.assertEquals;
import java.util.Arrays;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.user.UserPermissions;
import org.alfresco.rest.rm.community.model.user.UserRoles;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RMUserAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMUserAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RecordCategoryAPI;
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.constants.UserRole;
import org.alfresco.utility.model.SiteModel;
import org.alfresco.utility.model.UserModel;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
@@ -58,10 +71,100 @@ import org.testng.annotations.Test;
* @since 2.6
*/
public class UpdateRecordsTests extends BaseRMRestTest
{
{
/* to be used to append to modifications */
private final String MODIFIED_PREFIX = "modified_";
/** Incomplete electronic and non electronic records created in one record folder, unfiled records container and one unfiled record folder */
@DataProvider(name = "incompleteRecords")
public String[][] getIncompleteRecords() throws Exception
{
//create electronic and nonElectronic record in record folder
String recordFolderId = createCategoryFolderInFilePlan().getId();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
Record electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolderId, getFile(IMAGE_FILE));
assertStatusCode(CREATED);
Record nonElectronicRecord = recordFolderAPI.createRecord(createNonElectronicRecordModel(), recordFolderId);
assertStatusCode(CREATED);
//create electronic record and nonElectronic record in unfiled records container
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild electronicRecord1 = unfiledContainersAPI.uploadRecord(createElectronicUnfiledContainerChildModel(), UNFILED_RECORDS_CONTAINER_ALIAS, getFile(IMAGE_FILE));
assertStatusCode(CREATED);
UnfiledContainerChild nonElectronicRecord1 = unfiledContainersAPI.createUnfiledContainerChild(createNonElectronicUnfiledContainerChildModel(), UNFILED_RECORDS_CONTAINER_ALIAS);
assertStatusCode(CREATED);
//create electronic record and nonElectronic record in unfiled record folder
String unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild electronicRecord2 = unfiledRecordFoldersAPI.uploadRecord(createElectronicUnfiledContainerChildModel(), unfiledRecordFolderId, getFile(IMAGE_FILE));
assertStatusCode(CREATED);
UnfiledContainerChild nonElectronicRecord2 = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(createNonElectronicUnfiledContainerChildModel(), unfiledRecordFolderId);
assertStatusCode(CREATED);
return new String[][]
{
// an arbitrary record folder
{ electronicRecord.getId(), nonElectronicRecord.getId()},
// unfiled records root
{ electronicRecord1.getId(), nonElectronicRecord1.getId()},
// an arbitrary unfiled records folder
{ electronicRecord2.getId(), nonElectronicRecord2.getId()}
};
}
/** Complete electronic and non electronic records created in one record folder, unfiled records container and one unfiled record folder */
@DataProvider(name = "completeRecords")
public String[][] getCompleteRecords() throws Exception
{
//create electronic and nonElectronic record in record folder
String recordFolderId = createCategoryFolderInFilePlan().getId();
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
Record electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolderId, getFile(IMAGE_FILE));
assertStatusCode(CREATED);
completeRecord(electronicRecord.getId());
Record nonElectronicRecord = recordFolderAPI.createRecord(createNonElectronicRecordModel(), recordFolderId);
assertStatusCode(CREATED);
completeRecord(nonElectronicRecord.getId());
//create electronic record and nonElectronic record in unfiled records container
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
UnfiledContainerChild electronicRecord1 = unfiledContainersAPI.uploadRecord(createElectronicUnfiledContainerChildModel(), UNFILED_RECORDS_CONTAINER_ALIAS, getFile(IMAGE_FILE));
assertStatusCode(CREATED);
completeRecord(electronicRecord1.getId());
UnfiledContainerChild nonElectronicRecord1 = unfiledContainersAPI.createUnfiledContainerChild(createNonElectronicUnfiledContainerChildModel(), UNFILED_RECORDS_CONTAINER_ALIAS);
assertStatusCode(CREATED);
completeRecord(nonElectronicRecord1.getId());
//create electronic record and nonElectronic record in unfiled record folder
String unfiledRecordFolderId = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS, "Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE).getId();
UnfiledRecordFolderAPI unfiledRecordFoldersAPI = getRestAPIFactory().getUnfiledRecordFoldersAPI();
UnfiledContainerChild electronicRecord2 = unfiledRecordFoldersAPI.uploadRecord(createElectronicUnfiledContainerChildModel(), unfiledRecordFolderId, getFile(IMAGE_FILE));
assertStatusCode(CREATED);
completeRecord(electronicRecord2.getId());
UnfiledContainerChild nonElectronicRecord2 = unfiledRecordFoldersAPI.createUnfiledRecordFolderChild(createNonElectronicUnfiledContainerChildModel(), unfiledRecordFolderId);
assertStatusCode(CREATED);
completeRecord(nonElectronicRecord2.getId());
return new String[][]
{
// an arbitrary record folder
{ electronicRecord.getId(), nonElectronicRecord.getId()},
// unfiled records root
{ electronicRecord1.getId(), nonElectronicRecord1.getId()},
// an arbitrary unfiled records folder
{ electronicRecord2.getId(), nonElectronicRecord2.getId()}
};
}
/**
* <pre>
* Given an incomplete record
@@ -72,40 +175,30 @@ public class UpdateRecordsTests extends BaseRMRestTest
*/
@Test
(
dataProvider = "validRootContainers",
dataProvider = "incompleteRecords",
description = "Incomplete records can be updated"
)
@AlfrescoTest(jira="RM-4362")
public void incompleteRecordsCanBeUpdated(FilePlanComponent recordFolder) throws Exception
public void incompleteRecordsCanBeUpdated(String electronicRecordId, String nonElectronicRecordId) throws Exception
{
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
// Get the recordsAPI
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
Record electronicRecord = recordsAPI.getRecord(electronicRecordId);
Record nonElectronicRecord = recordsAPI.getRecord(nonElectronicRecordId);
// create electronic and non-electronic records in a folder
FilePlanComponent electronicRecord = filePlanComponentsAPI.createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, recordFolder.getId());
assertStatusCode(CREATED);
FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), recordFolder.getId());
assertStatusCode(CREATED);
for (FilePlanComponent record: Arrays.asList(electronicRecord, nonElectronicRecord)) {
// generate update metadata
for (Record record: Arrays.asList(electronicRecord, nonElectronicRecord)) {
// Generate update metadata
String newName = getModifiedPropertyValue(record.getName());
String newTitle = getModifiedPropertyValue(record.getProperties().getTitle());
String newDescription = getModifiedPropertyValue(record.getProperties().getDescription());
Record recordModel = createRecordModel(newName, newDescription, newTitle);
FilePlanComponent updateRecord = FilePlanComponent.builder()
.name(newName)
.properties(FilePlanComponentProperties.builder()
.description(newDescription)
.title(newTitle)
.build())
.build();
// update record
filePlanComponentsAPI.updateFilePlanComponent(updateRecord, record.getId());
// Update record
recordsAPI.updateRecord(recordModel, record.getId());
assertStatusCode(OK);
// verify the update got applied
FilePlanComponent updatedRecord = filePlanComponentsAPI.getFilePlanComponent(record.getId());
// Verify the original record meta data has been retained
Record updatedRecord = recordsAPI.getRecord(record.getId());
assertEquals(updatedRecord.getName(), newName);
assertEquals(updatedRecord.getProperties().getTitle(), newTitle);
assertEquals(updatedRecord.getProperties().getDescription(), newDescription);
@@ -127,9 +220,9 @@ public class UpdateRecordsTests extends BaseRMRestTest
)
@AlfrescoTest(jira="RM-4362")
public void userWithEditMetadataCapsCanUpdateMetadata() throws Exception
{
{
RMUserAPI rmUserAPI = getRestAPIFactory().getRMUserAPI();
// create test user and add it with collab. privileges
// Create test user and add it with collab. privileges
UserModel updateUser = getDataUser().createRandomTestUser("updateuser");
updateUser.setUserRole(UserRole.SiteCollaborator);
getDataUser().addUserToSite(updateUser, new SiteModel(getRestAPIFactory().getRMSiteAPI().getSite().getId()), UserRole.SiteCollaborator);
@@ -138,50 +231,44 @@ public class UpdateRecordsTests extends BaseRMRestTest
rmUserAPI.assignRoleToUser(updateUser.getUsername(), UserRoles.ROLE_RM_SECURITY_OFFICER);
assertStatusCode(OK);
// create random folder
FilePlanComponent randomFolder = createCategoryFolderInFilePlan();
logger.info("random folder:" + randomFolder.getName());
// Create random folder
RecordCategoryChild recordFolder = createCategoryFolderInFilePlan();
logger.info("random folder:" + recordFolder.getName());
// grant updateUser Filing privileges on randomFolder category, this will be
// inherited to randomFolder
FilePlanComponentAPI filePlanComponentsAPIAsAdmin = getRestAPIFactory().getFilePlanComponentsAPI();
rmUserAPI.addUserPermission(filePlanComponentsAPIAsAdmin.getFilePlanComponent(randomFolder.getParentId()),
// Grant updateUser Filing privileges on randomFolder category, this will be
// Inherited to randomFolder
RecordCategoryAPI recordCategoryAPI = getRestAPIFactory().getRecordCategoryAPI();
rmUserAPI.addUserPermission(recordCategoryAPI.getRecordCategory(recordFolder.getParentId()).getId(),
updateUser, UserPermissions.PERMISSION_FILING);
assertStatusCode(OK);
// create electronic and non-electronic records in a folder
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
FilePlanComponent electronicRecord = filePlanComponentsAPI.createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, randomFolder.getId());
// Create electronic and non-electronic records in a folder
RecordFolderAPI recordFolderAPI = getRestAPIFactory().getRecordFolderAPI();
Record electronicRecord = recordFolderAPI.createRecord(createElectronicRecordModel(), recordFolder.getId(), getFile(IMAGE_FILE));
assertStatusCode(CREATED);
FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), randomFolder.getId());
Record nonElectronicRecord = recordFolderAPI.createRecord(createNonElectronicRecordModel(), recordFolder.getId());
assertStatusCode(CREATED);
// get FilePlanComponentAPI instance initialised to updateUser
FilePlanComponentAPI filePlanComponentsAPIAsUser = getRestAPIFactory().getFilePlanComponentsAPI(updateUser);
// Get recordsAPI instance initialised to updateUser
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI(updateUser);
for (FilePlanComponent record: Arrays.asList(electronicRecord, nonElectronicRecord)) {
filePlanComponentsAPIAsUser.getFilePlanComponent(record.getId());
for (Record record: Arrays.asList(electronicRecord, nonElectronicRecord))
{
recordsAPI.getRecord(record.getId());
assertStatusCode(OK);
// generate update metadata
// Generate update metadata
String newName = getModifiedPropertyValue(record.getName());
String newTitle = getModifiedPropertyValue(record.getProperties().getTitle());
String newDescription = getModifiedPropertyValue(record.getProperties().getDescription());
Record recordModel = createRecordModel(newName, newDescription, newTitle);
FilePlanComponent updateRecord = FilePlanComponent.builder()
.name(newName)
.properties(FilePlanComponentProperties.builder()
.description(newDescription)
.title(newTitle)
.build())
.build();
// update record
filePlanComponentsAPIAsUser.updateFilePlanComponent(updateRecord, record.getId());
// Update record
recordsAPI.updateRecord(recordModel, record.getId());
assertStatusCode(OK);
// verify the update got applied
FilePlanComponent updatedRecord = filePlanComponentsAPIAsUser.getFilePlanComponent(record.getId());
// Verify the update got applied
Record updatedRecord = recordsAPI.getRecord(record.getId());
assertEquals(updatedRecord.getName(), newName);
assertEquals(updatedRecord.getProperties().getTitle(), newTitle);
assertEquals(updatedRecord.getProperties().getDescription(), newDescription);
@@ -200,46 +287,33 @@ public class UpdateRecordsTests extends BaseRMRestTest
*/
@Test
(
dataProvider = "validRootContainers",
dataProvider = "completeRecords",
description = "Complete records can't be updated"
)
@AlfrescoTest(jira="RM-4362")
public void completeRecordsCantBeUpdated(FilePlanComponent recordFolder) throws Exception
public void completeRecordsCantBeUpdated(String electronicRecordId, String nonElectronicRecordId) throws Exception
{
FilePlanComponentAPI filePlanComponentsAPI = getRestAPIFactory().getFilePlanComponentsAPI();
// Get the recordsAPI
RecordsAPI recordsAPI = getRestAPIFactory().getRecordsAPI();
Record electronicRecord = recordsAPI.getRecord(electronicRecordId);
Record nonElectronicRecord = recordsAPI.getRecord(nonElectronicRecordId);
// create electronic and non-electronic records in a folder
FilePlanComponent electronicRecord = filePlanComponentsAPI.createElectronicRecord(createElectronicRecordModel(), IMAGE_FILE, recordFolder.getId());
assertStatusCode(CREATED);
closeRecord(electronicRecord);
FilePlanComponent nonElectronicRecord = filePlanComponentsAPI.createFilePlanComponent(createNonElectronicRecordModel(), recordFolder.getId());
assertStatusCode(CREATED);
closeRecord(nonElectronicRecord);
for (FilePlanComponent record: Arrays.asList(electronicRecord, nonElectronicRecord)) {
// generate update metadata
for (Record record: Arrays.asList(electronicRecord, nonElectronicRecord)) {
// Generate update metadata
String newName = getModifiedPropertyValue(record.getName());
String newTitle = getModifiedPropertyValue(record.getProperties().getTitle());
String newDescription = getModifiedPropertyValue(record.getProperties().getDescription());
Record recordModel = createRecordModel(newName, newDescription, newTitle);
FilePlanComponent updateRecord = FilePlanComponent.builder()
.name(newName)
.properties(FilePlanComponentProperties.builder()
.description(newDescription)
.title(newTitle)
.build())
.build();
// attempt to update record
filePlanComponentsAPI.updateFilePlanComponent(updateRecord, record.getId());
// Update record
recordsAPI.updateRecord(recordModel, record.getId());
assertStatusCode(FORBIDDEN);
// verify the original record metatada has been retained
FilePlanComponent updatedRecord = filePlanComponentsAPI.getFilePlanComponent(record.getId());
// Verify the original record meta data has been retained
Record updatedRecord = recordsAPI.getRecord(record.getId());
assertEquals(updatedRecord.getName(), record.getName());
assertEquals(updatedRecord.getProperties().getTitle(), record.getProperties().getTitle());
assertEquals(updatedRecord.getProperties().getDescription(), record.getProperties().getTitle());
assertEquals(updatedRecord.getProperties().getDescription(), record.getProperties().getDescription());
}
}

View File

@@ -41,13 +41,12 @@ import java.util.stream.Collectors;
import org.alfresco.dataprep.CMISUtil;
import org.alfresco.rest.model.RestNodeModel;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentEntry;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.requests.igCoreAPI.FilePlanComponentAPI;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordProperties;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildEntry;
import org.alfresco.rest.rm.community.requests.gscore.api.UnfiledContainerAPI;
import org.alfresco.test.AlfrescoTest;
import org.alfresco.utility.constants.UserRole;
import org.alfresco.utility.data.DataUser;
import org.alfresco.utility.model.FileModel;
import org.alfresco.utility.model.FolderModel;
import org.alfresco.utility.model.SiteModel;
@@ -55,7 +54,6 @@ import org.alfresco.utility.model.UserModel;
import org.apache.chemistry.opencmis.client.api.Document;
import org.apache.chemistry.opencmis.client.api.SecondaryType;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -67,9 +65,6 @@ import org.testng.annotations.Test;
*/
public class DeclareDocumentAsRecordTests extends BaseRMRestTest
{
@Autowired
private DataUser dataUser;
private UserModel testUser, testUserReadOnly;
private SiteModel testSite;
private FolderModel testFolder;
@@ -78,13 +73,13 @@ public class DeclareDocumentAsRecordTests extends BaseRMRestTest
public void declareDocumentAsRecordSetup() throws Exception
{
// create test user and test collaboration site to store documents in
testUser = dataUser.createRandomTestUser();
testUserReadOnly = dataUser.createRandomTestUser();
testUser = getDataUser().createRandomTestUser();
testUserReadOnly = getDataUser().createRandomTestUser();
testSite = dataSite.usingAdmin().createPublicRandomSite();
dataUser.addUserToSite(testUser, testSite, UserRole.SiteContributor);
dataUser.addUserToSite(testUserReadOnly, testSite, UserRole.SiteConsumer);
getDataUser().addUserToSite(testUser, testSite, UserRole.SiteContributor);
getDataUser().addUserToSite(testUserReadOnly, testSite, UserRole.SiteConsumer);
testFolder = dataContent.usingSite(testSite).usingUser(testUser).createFolder();
}
@@ -112,15 +107,15 @@ public class DeclareDocumentAsRecordTests extends BaseRMRestTest
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
// declare document as record
FilePlanComponent record = getRestAPIFactory().getFilesAPI(testUser).declareAsRecord(document.getNodeRefWithoutVersion());
Record record = getRestAPIFactory().getFilesAPI(testUser).declareAsRecord(document.getNodeRefWithoutVersion());
assertStatusCode(CREATED);
// verify the declared record is in Unfiled Records folder
FilePlanComponentAPI filePlanComponentAPI = getRestAPIFactory().getFilePlanComponentsAPI();
List<FilePlanComponentEntry> matchingRecords = filePlanComponentAPI.listChildComponents(UNFILED_RECORDS_CONTAINER_ALIAS)
UnfiledContainerAPI unfiledContainersAPI = getRestAPIFactory().getUnfiledContainersAPI();
List<UnfiledContainerChildEntry> matchingRecords = unfiledContainersAPI.getUnfiledContainerChildren(UNFILED_RECORDS_CONTAINER_ALIAS)
.getEntries()
.stream()
.filter(e -> e.getFilePlanComponentModel().getId().equals(document.getNodeRefWithoutVersion()))
.filter(e -> e.getEntry().getId().equals(document.getNodeRefWithoutVersion()))
.collect(Collectors.toList());
// there should be only one matching record corresponding this document
assertEquals(matchingRecords.size(), 1, "More than one record matching document name");
@@ -136,7 +131,7 @@ public class DeclareDocumentAsRecordTests extends BaseRMRestTest
// verify the new name has the form of "<original name> (<record Id>).<original extension>"
String recordName = filesAfterRename.get(0).onModel().getName();
assertEquals(recordName, document.getName().replace(".", String.format(" (%s).", record.getProperties().getRmIdentifier())));
assertEquals(recordName, document.getName().replace(".", String.format(" (%s).", record.getProperties().getIdentifier())));
// verify the document in collaboration site is now a record, note the file is now renamed hence folder + doc. name concatenation
// this also verifies the document is still in the initial folder
@@ -208,16 +203,16 @@ public class DeclareDocumentAsRecordTests extends BaseRMRestTest
public void recordCantBeDeclaredARecord() throws Exception
{
// create a non-electronic record in a random folder
FilePlanComponent nonelectronicRecord = FilePlanComponent.builder()
.properties(FilePlanComponentProperties.builder()
Record nonelectronicRecord = Record.builder()
.properties(RecordProperties.builder()
.description("Description")
.title("Title")
.build())
.name("Non-Electronic Record")
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.build();
FilePlanComponent record = getRestAPIFactory().getFilePlanComponentsAPI()
.createFilePlanComponent(nonelectronicRecord, createCategoryFolderInFilePlan().getId());
Record record = getRestAPIFactory().getRecordFolderAPI()
.createRecord(nonelectronicRecord, createCategoryFolderInFilePlan().getId());
assertStatusCode(CREATED);
// try to declare it as a record

View File

@@ -51,7 +51,7 @@ import static org.testng.Assert.assertNotNull;
import org.alfresco.rest.rm.community.base.BaseRMRestTest;
import org.alfresco.rest.rm.community.base.TestData;
import org.alfresco.rest.rm.community.model.site.RMSite;
import org.alfresco.rest.rm.community.requests.igCoreAPI.RMSiteAPI;
import org.alfresco.rest.rm.community.requests.gscore.api.RMSiteAPI;
import org.alfresco.utility.data.RandomData;
import org.alfresco.utility.model.UserModel;
import org.alfresco.utility.report.Bug;

View File

@@ -26,17 +26,32 @@
*/
package org.alfresco.rest.rm.community.utils;
import static java.nio.charset.Charset.forName;
import static com.google.common.io.Resources.getResource;
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.RECORD_CATEGORY_TYPE;
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.RECORD_FOLDER_TYPE;
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponent;
import org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentProperties;
import org.alfresco.rest.rm.community.model.record.Record;
import org.alfresco.rest.rm.community.model.record.RecordProperties;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategory;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChild;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryChildProperties;
import org.alfresco.rest.rm.community.model.recordcategory.RecordCategoryProperties;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolder;
import org.alfresco.rest.rm.community.model.recordfolder.RecordFolderProperties;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChild;
import org.alfresco.rest.rm.community.model.unfiledcontainer.UnfiledContainerChildProperties;
/**
* Utility class for file plan component models
@@ -51,18 +66,35 @@ public class FilePlanComponentsUtil
// Intentionally blank
}
/** image resource file to be used for records body */
/** Name of the image resource file to be used for records body */
public static final String IMAGE_FILE = "money.JPG";
/** Title prefix for record category children */
public static final String TITLE_PREFIX = "Title for ";
/** Description prefix for record category children */
public static final String DESCRIPTION_PREFIX = "This is the description for";
/**
* Helper method to get a file by its name
*
* @return The file
*/
public static File getFile(String fileName)
{
return new File(getResource(fileName).getFile());
}
/**
* Creates a record model with the given type and a random name (with "Record " prefix)
*
* @param nodeType The node type
* @return The {@link FilePlanComponent} with for the given node type
* @return The {@link Record} with for the given node type
*/
private static FilePlanComponent createRecordModel(String nodeType)
private static Record createRecordModel(String nodeType)
{
return FilePlanComponent.builder()
return Record.builder()
.name("Record " + getRandomAlphanumeric())
.nodeType(nodeType)
.build();
@@ -71,67 +103,254 @@ public class FilePlanComponentsUtil
/**
* Creates an electronic record model with a random name (with "Record " prefix)
*
* @return The electronic record as {@link FilePlanComponent}
* @return The electronic record as {@link Record}
*/
public static FilePlanComponent createElectronicRecordModel()
public static Record createElectronicRecordModel()
{
return createRecordModel(CONTENT_TYPE);
}
/**
* Creates a non-electronic unfiled container child model with a random name (with "Record " prefix)
*
* @return The electronic record as {@link UnfiledContainerChild}
*/
public static UnfiledContainerChild createElectronicUnfiledContainerChildModel()
{
return createUnfiledContainerChildRecordModel("Record " + getRandomAlphanumeric(), CONTENT_TYPE);
}
/**
* Creates an electronic unfiled container child model with a random name (with "Record " prefix)
*
* @return The electronic record as {@link UnfiledContainerChild}
*/
public static UnfiledContainerChild createNonElectronicUnfiledContainerChildModel()
{
return createUnfiledContainerChildRecordModel("Record " + getRandomAlphanumeric(), NON_ELECTRONIC_RECORD_TYPE);
}
/**
* Creates an unfiled records container child record model with the given name and type
*
* @param name The name of the unfiled records container child
* @param nodeType The type of the record category child
* @return The {@link UnfiledContainerChild} with the given details
*/
public static UnfiledContainerChild createUnfiledContainerChildRecordModel(String name, String nodeType)
{
return UnfiledContainerChild.builder()
.name(name)
.nodeType(nodeType)
.build();
}
/**
* Creates a nonElectronic container child record model with all available properties for the non electronic records
*
* @param name The name of the unfiled records container child
* @param nodeType The type of the record category child
* @return The {@link UnfiledContainerChild} with the given details
*/
public static UnfiledContainerChild createFullNonElectronicUnfiledContainerChildRecordModel(String name, String title, String description, String box, String file,
String shelf, String storageLocation, Integer numberOfCopies, Integer physicalSize)
{
return UnfiledContainerChild.builder()
.name(name)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.properties(UnfiledContainerChildProperties.builder()
.title(title)
.description(description)
.box(box)
.file(file)
.shelf(shelf)
.storageLocation(storageLocation)
.numberOfCopies(numberOfCopies)
.physicalSize(physicalSize)
.build())
.build();
}
/**
* Creates a non-electronic record model with a random name (with "Record " prefix)
*
* @return The non-electronic record as {@link FilePlanComponent}
* @return The non-electronic record as {@link Record}
*/
public static FilePlanComponent createNonElectronicRecordModel()
public static Record createNonElectronicRecordModel()
{
return createRecordModel(NON_ELECTRONIC_RECORD_TYPE);
}
/**
* Creates a file plan component with the given name, type and title
* Creates a non-electronic record model with with all available properties for the non electronic records
*
* @param name The name of the file plan component
* @param type The type of the file plan component
* @param title The title of the file plan component
* @return The {@link FilePlanComponent} with the given details
* @return The non-electronic record as {@link Record}
*/
public static FilePlanComponent createFilePlanComponentModel(String name, String type, String title)
public static Record createFullNonElectronicRecordModel(String name, String title, String description, String box, String file,
String shelf, String storageLocation, Integer numberOfCopies, Integer physicalSize)
{
return FilePlanComponent.builder()
return Record.builder()
.name(name)
.nodeType(NON_ELECTRONIC_RECORD_TYPE)
.properties(RecordProperties.builder()
.title(title)
.description(description)
.box(box)
.file(file)
.shelf(shelf)
.storageLocation(storageLocation)
.numberOfCopies(numberOfCopies)
.physicalSize(physicalSize)
.build())
.build();
}
/**
* Creates a record model with the given name, description and title
*
* @param name The name of the record
* @param description The description of the record
* @param title The title of the record
* @return The {@link Record} with the given details
*/
public static Record createRecordModel(String name, String description, String title)
{
return Record.builder()
.name(name)
.nodeType(type)
.properties(FilePlanComponentProperties.builder()
.title(title)
.build())
.properties(RecordProperties.builder()
.description(description)
.title(title)
.build())
.build();
}
/**
* Creates a record category child model with the given name and type
*
* @param name The name of the record category child
* @param nodeType The type of the record category child
* @return The {@link RecordCategoryChild} with the given details
*/
public static RecordCategoryChild createRecordCategoryChildModel(String name, String nodeType)
{
return RecordCategoryChild.builder()
.name(name)
.nodeType(nodeType)
.properties(RecordCategoryChildProperties.builder()
.title(TITLE_PREFIX + name)
.build())
.build();
}
/**
* Creates a record category model with the given name and title
*
* @param name The name of the record category
* @param title The title of the record category
* @return The {@link RecordCategory} with the given details
*/
public static RecordCategory createRecordCategoryModel(String name, String title)
{
return RecordCategory.builder()
.name(name)
.nodeType(RECORD_CATEGORY_TYPE)
.properties(RecordCategoryProperties.builder()
.title(title)
.build())
.build();
}
/**
* Creates a record folder model with the given name and title
*
* @param name The name of the record folder
* @param title The title of the record folder
* @return The {@link RecordFolder} with the given details
*/
public static RecordFolder createRecordFolderModel(String name, String title)
{
return RecordFolder.builder()
.name(name)
.nodeType(RECORD_FOLDER_TYPE)
.properties(RecordFolderProperties.builder()
.title(title)
.build())
.build();
}
/**
* Creates an unfiled records container child model with the given name and type
*
* @param name The name of the unfiled records container child
* @param nodeType The type of the record category child
* @return The {@link UnfiledContainerChild} with the given details
*/
public static UnfiledContainerChild createUnfiledContainerChildModel(String name, String nodeType)
{
return UnfiledContainerChild.builder()
.name(name)
.nodeType(nodeType)
.properties(UnfiledContainerChildProperties.builder()
.title(TITLE_PREFIX + name)
.build())
.build();
}
/**
* Create temp file with content
*
* @param name file name
* @return {@link File} file
* @param name The file name
* @return {@link File} The created file
*/
public static File createTempFile(final String name, String content)
{
try
{
// create file
// Create file
final File file = File.createTempFile(name, ".txt");
// create writer
try (FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(fos, Charset.forName("UTF-8").newEncoder()))
// Create writer
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), forName("UTF-8").newEncoder()))
{
// place content in file
writer.write(content);
}
return file;
} catch (Exception exception)
}
catch (Exception exception)
{
throw new RuntimeException("Unable to create test file.", exception);
}
}
/**
* Helper method to verify all properties of a nonElectronic record
*
* @param nonElectronicRecord
* @param name
* @param title
* @param description
* @param box
* @param file
* @param shelf
* @param storageLocation
* @param numberOfCopies
* @param physicalSize
*/
public static void verifyFullNonElectronicRecord(Record nonElectronicRecord, String name, String title, String description, String box, String file,
String shelf, String storageLocation, Integer numberOfCopies, Integer physicalSize)
{
RecordProperties properties = nonElectronicRecord.getProperties();
assertEquals(title, properties.getTitle());
assertEquals(description, properties.getDescription());
assertEquals(box, properties.getBox());
assertEquals(file, properties.getFile());
assertEquals(shelf, properties.getShelf());
assertEquals(storageLocation, properties.getStorageLocation());
assertEquals(numberOfCopies, properties.getNumberOfCopies());
assertEquals(physicalSize, properties.getPhysicalSize());
assertTrue(nonElectronicRecord.getName().contains(properties.getIdentifier()));
assertTrue(nonElectronicRecord.getName().contains(name));
}
}

View File

@@ -6,7 +6,7 @@
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="rm.quickShareLinks" parent="quickShareLinks">
<property name="nodes" ref="rm.nodes"/>
<property name="nodes" ref="nodes"/>
</bean>
<bean id="rm.QuickShareLinks" class="org.springframework.aop.framework.ProxyFactoryBean">
@@ -23,43 +23,145 @@
</property>
</bean>
<bean id="rm.nodes" class="org.alfresco.rm.rest.api.impl.RMNodesImpl" parent="nodes" init-method="init">
<property name="quickShareLinks" ref="rm.QuickShareLinks"/>
<property name="filePlanService" ref="FilePlanService"/>
<property name="recordsManagementServiceRegistry" ref="RecordsManagementServiceRegistry"/>
<property name="capabilityService" ref="CapabilityService"/>
<bean id="nodesModelFactory" class="org.alfresco.rm.rest.api.impl.ApiNodesModelFactory">
<property name="nodes" ref="nodes" />
<property name="nodeService" ref="NodeService"/>
<property name="namespaceService" ref="NamespaceService"/>
<property name="apiUtils" ref="apiUtils" />
<property name="personService" ref="PersonService"/>
<property name="dispositionService" ref="DispositionService"/>
<property name="serviceRegistry" ref="ServiceRegistry"/>
</bean>
<bean id="searchTypesFactory" class="org.alfresco.rm.rest.api.impl.SearchTypesFactory">
<property name="dictionaryService" ref="DictionaryService" />
<property name="nodes" ref="nodes" />
</bean>
<bean id="apiUtils" class="org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils">
<property name="nodes" ref="nodes" />
<property name="nodeService" ref="NodeService"/>
<property name="fileFolderService" ref="FileFolderService"/>
<property name="filePlanService" ref="FilePlanService"/>
<property name="contentService" ref="ContentService"/>
<property name="mimetypeService" ref="MimetypeService"/>
<property name="dictionaryService" ref="DictionaryService"/>
<property name="capabilityService" ref="CapabilityService"/>
<property name="permissionService" ref="PermissionService"/>
<property name="recordService" ref="RecordService"/>
<property name="authenticationUtil" ref="rm.authenticationUtil"/>
<property name="activityPoster" ref="activitiesPoster"/>
<property name="sites" ref="rm.sites"/>
</bean>
<bean id="rm.Nodes" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.rm.rest.api.RMNodes</value>
</property>
<property name="target">
<ref bean="rm.nodes" />
</property>
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
<bean class="org.alfresco.rm.rest.api.fileplans.FilePlanEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="fileFolderService" ref="FileFolderService" />
</bean>
<bean class="org.alfresco.rm.rest.api.fileplancomponents.FileplanComponentsEntityResource">
<property name="nodes" ref="rm.Nodes" />
<bean class="org.alfresco.rm.rest.api.fileplans.FilePlanChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.fileplancomponents.FileplanComponentChildrenRelation">
<property name="nodes" ref="rm.Nodes" />
<bean class="org.alfresco.rm.rest.api.unfiledcontainers.UnfiledContainerEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.unfiledcontainers.UnfiledContainerChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.unfiledrecordfolders.UnfiledRecordFolderEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.unfiledrecordfolders.UnfiledRecordFolderChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.recordcategories.RecordCategoriesEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.recordcategories.RecordCategoryChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.recordfolders.RecordFolderEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.recordfolders.RecordFolderChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="transactionService" ref="transactionService" />
</bean>
<bean class="org.alfresco.rm.rest.api.records.RecordsEntityResource">
<property name="nodes" ref="rm.Nodes" />
<property name="records" ref="Records" />
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="recordService" ref="RecordService"/>
<property name="nodeService" ref="NodeService"/>
</bean>
<bean class="org.alfresco.rm.rest.api.files.FilesEntityResource">
<property name="records" ref="Records" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
<property name="filePlanService" ref="FilePlanService"/>
<property name="recordService" ref="RecordService"/>
<property name="authenticationUtil" ref="rm.authenticationUtil"/>
</bean>
<bean class="org.alfresco.rm.rest.api.transfercontainers.TransferContainerEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.transfercontainers.TransferContainerChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.transfers.TransferEntityResource">
<property name="apiUtils" ref="apiUtils" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<bean class="org.alfresco.rm.rest.api.transfers.TransferChildrenRelation">
<property name="apiUtils" ref="apiUtils" />
<property name="searchTypesFactory" ref="searchTypesFactory" />
<property name="fileFolderService" ref="FileFolderService" />
<property name="nodesModelFactory" ref="nodesModelFactory" />
</bean>
<!-- extended sites bean definition -->
@@ -89,37 +191,13 @@
<property name="sites" ref="rm.Sites" />
</bean>
<bean id="records" class="org.alfresco.rm.rest.api.impl.RecordsImpl">
<property name="recordService" ref="RecordService"/>
<property name="filePlanService" ref="FilePlanService"/>
<property name="nodes" ref="rm.nodes"/>
<property name="nodeService" ref="NodeService"/>
<property name="fileFolderService" ref="FileFolderService"/>
<property name="dictionaryService" ref="DictionaryService"/>
<property name="authenticationUtil" ref="rm.authenticationUtil"/>
</bean>
<bean id="Records" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>org.alfresco.rm.rest.api.Records</value>
</property>
<property name="target">
<ref bean="records" />
</property>
<property name="interceptorNames">
<list>
<idref bean="legacyExceptionInterceptor" />
</list>
</property>
</bean>
<!-- Map RM exceptions to HTML status codes -->
<bean id="rm.simpleMappingExceptionResolver" abstract="true" parent="simpleMappingExceptionResolver">
<property name="exceptionMappings">
<map merge="true">
<entry key="org.alfresco.service.cmr.attributes.DuplicateAttributeException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_CONFLICT}" />
<entry key="org.alfresco.module.org_alfresco_module_rm.record.RecordCreationException" value="422" />
<entry key="org.alfresco.service.cmr.model.FileExistsException" value="409" />
</map>
</property>
</bean>

View File

@@ -577,7 +577,7 @@
<groupId>org.alfresco</groupId>
<artifactId>alfresco-rm-community-rest-api-explorer</artifactId>
<version>${project.version}</version>
<contextPath>/ig-api-explorer</contextPath>
<contextPath>/gs-api-explorer</contextPath>
<type>war</type>
<asWebapp>true</asWebapp>
</webapp>

View File

@@ -28,8 +28,11 @@
package org.alfresco.rm.rest.api;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.springframework.extensions.webscripts.servlet.FormData;
/**
* RM Nodes API
@@ -37,6 +40,7 @@ import org.alfresco.service.namespace.QName;
* @author Ana Bozianu
* @since 2.6
*/
@Deprecated
public interface RMNodes extends Nodes
{
public static String PATH_FILE_PLAN = "-filePlan-";
@@ -47,10 +51,13 @@ public interface RMNodes extends Nodes
public static String PARAM_INCLUDE_HAS_RETENTION_SCHEDULE = "hasRetentionSchedule";
public static String PARAM_INCLUDE_IS_CLOSED = "isClosed";
public static String PARAM_INCLUDE_IS_COMPLETED = "isCompleted";
public static String PARAM_INCLUDE_TRANSFER_PDF_INDICATOR = "transferPDFIndicator";
public static String PARAM_INCLUDE_TRANSFER_LOCATION = "transferLocation";
public static String PARAM_INCLUDE_TRANSFER_ACCESSION_INDICATOR = "transferAccessionIndicator";
/**
* Gets or creates the relative path starting from the provided parent folder.
* The method decides the type of the created elements considering the
* The method decides the type of the created elements considering the
* parent container's type and the type of the node to be created.
* @param parentFolderNodeId the parent folder to start from
* @param relativePath the relative path
@@ -58,4 +65,46 @@ public interface RMNodes extends Nodes
* @return reference to the last element of the created path
*/
public NodeRef getOrCreatePath(String parentFolderNodeId, String relativePath, QName nodeTypeQName);
/**
* Validates if the component with provided id and provided parameters belongs to the current endpoint.
*
* @param filePlanComponentId - file plan component id to check
* @param parameters - provided parameters
* @param requestedTypeQName - the requested type that identifies the endpoint we are in
*/
public void validateNodeType(String filePlanComponentId, Parameters parameters, QName requestedTypeQName);
/**
* Validates if the component with provided id and provided parameters from formData belongs to the current endpoint.
*
* @param filePlanComponentId - file plan component id to check
* @param formData - provided formData
* @param requestedTypeQName - the requested type that identifies the endpoint we are in
*/
public void validateNodeType(String filePlanComponentId, FormData formData, QName requestedTypeQName);
/**
* Validates if the component with provided id, relativePath from new created filePlanComponent and provided parameters belongs to the current endpoint.
*
* @param filePlanComponentId - file plan component id to check
* @param filePlanComponentInfo - new created file plan component info
* @param parameters - provided parameters
* @param requestedTypeQName - the requested type that identifies the endpoint we are in
*/
public void validateNodeType(String filePlanComponentId, Node filePlanComponentInfo, Parameters parameters, QName requestedTypeQName);
/**
* Validates if the filePlanComponent with provided id is a record.
*
* @param filePlanComponentId
*/
public void validateRecord(String filePlanComponentId);
/**
* Helper method to obtain file plan type or null if the rm site does not exist.
*
* @return file plan type or null
*/
public QName getFilePlanType();
}

View File

@@ -28,10 +28,9 @@
package org.alfresco.rm.rest.api;
import org.alfresco.rest.api.Sites;
import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.api.model.SiteUpdate;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.RMSite;
import org.alfresco.rm.rest.api.model.SiteUpdate;
/**
* RM Sites API
@@ -73,14 +72,4 @@ public interface RMSites extends Sites
* @param parameters
*/
void deleteRMSite(String siteId, Parameters parameters);
/**
* TODO Copied from Sites interface because was not available in 5.2.a-EA. To be removed after upgrading.
*
* @param siteId
* @param site
* @param parameters
* @return
*/
Site updateSite(String siteId, SiteUpdate site, Parameters parameters);
}

View File

@@ -1,63 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.TargetContainer;
/**
* Records API
*
* @author Ana Bozianu
* @since 2.6
*/
public interface Records
{
public static final String PARAM_HIDE_RECORD = "hideRecord";
/**
* Creates a record from a file
*
* @param fileId the id of a non record file
* @param parameters the {@link Parameters} object to get the parameters passed into the request
* @return information about the created record
*/
public Node declareFileAsRecord(String fileId, Parameters parameters);
/**
* Files a record into th fileplan.
* If the record is already filed it links the record to the target folder
*
* @param recordId the id of the record do file/link
* @param target the target parent folder
* @param parameters the {@link Parameters} object to get the parameters passed into the request
* @return information about the new state of the record
*/
public Node fileOrLinkRecord(String recordId, TargetContainer target, Parameters parameters);
}

View File

@@ -1,111 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.fileplancomponents;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.exceptions.ApiException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartRelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.webscripts.WithResponse;
import org.alfresco.rm.rest.api.RMNodes;
import org.springframework.extensions.webscripts.servlet.FormData;
/**
* An implementation of an Entity Resource for a fileplan component
*
* @author Ana Bozianu
* @since 2.6
*/
@RelationshipResource(name="children", entityResource = FileplanComponentsEntityResource.class, title = "Children of fileplan component")
public class FileplanComponentChildrenRelation implements RelationshipResourceAction.Read<Node>,
RelationshipResourceAction.Create<Node>,
MultiPartRelationshipResourceAction.Create<Node>
{
private RMNodes nodes;
public void setNodes(RMNodes nodes)
{
this.nodes = nodes;
}
@Override
@WebApiDescription(title = "Return a paged list of fileplan components for the container identified by parentFolderNodeId")
public CollectionWithPagingInfo<Node> readAll(String parentFolderNodeId, Parameters parameters)
{
return nodes.listChildren(parentFolderNodeId, parameters);
}
@Override
@WebApiDescription(title="Create one (or more) nodes as children of container identified by parentFolderNodeId")
public List<Node> create(String parentFolderNodeId, List<Node> nodeInfos, Parameters parameters)
{
List<Node> result = new ArrayList<>(nodeInfos.size());
for (Node nodeInfo : nodeInfos)
{
result.add(nodes.createNode(parentFolderNodeId, nodeInfo, parameters));
}
return result;
}
@Override
@WebApiDescription(title = "Upload file content and meta-data into the repository.")
@WebApiParam(name = "formData", title = "A single form data", description = "A single form data which holds FormFields.")
public Node create(String parentFolderNodeId, FormData formData, Parameters parameters, WithResponse withResponse)
{
try
{
return nodes.upload(parentFolderNodeId, formData, parameters);
}
catch (ApiException apiException)
{
/*
* The upload method encapsulates most exceptions that can occur on node creation in an ApiException.
* To allow the API framework to correctly map the exception to the API error code we throw the original exception.
*/
Throwable originalException = apiException.getCause();
if (originalException != null && originalException instanceof RuntimeException)
{
throw (RuntimeException) originalException;
}
else
{
throw apiException;
}
}
}
}

View File

@@ -1,93 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.fileplancomponents;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.RMNodes;
import org.alfresco.util.ParameterCheck;
import org.springframework.beans.factory.InitializingBean;
/**
* Fileplan component children
*
* @author Ana Bozianu
* @since 2.6
*/
@EntityResource(name="fileplan-components", title = "Fileplan Components")
public class FileplanComponentsEntityResource implements
EntityResourceAction.ReadById<Node>,
EntityResourceAction.Delete,
EntityResourceAction.Update<Node>,
InitializingBean
{
private RMNodes nodes;
private String PARAM_PERMANENT = "permanent";
public void setNodes(RMNodes nodes)
{
this.nodes = nodes;
}
@WebApiDescription(title = "Get Node Information", description = "Get information for the fileplan component with id 'nodeId'")
@WebApiParam(name = "nodeId", title = "The node id")
public Node readById(String nodeId, Parameters parameters)
{
return nodes.getFolderOrDocument(nodeId, parameters);
}
@Override
@WebApiDescription(title="Updates a node (file or folder) with id 'nodeId'")
public Node update(String nodeId, Node nodeInfo, Parameters parameters)
{
return nodes.updateNode(nodeId, nodeInfo, parameters);
}
@Override
@WebApiDescription(title = "Delete Node", description="Delete the file or folder with id 'nodeId'. Folder will cascade delete")
public void delete(String nodeId, Parameters parameters)
{
String permanentParameter = parameters.getParameter(PARAM_PERMANENT);
if(permanentParameter != null)
{
throw new InvalidArgumentException("DELETE does not support parameter: permanent");
}
nodes.deleteNode(nodeId, parameters);
}
@Override
public void afterPropertiesSet() throws Exception
{
ParameterCheck.mandatory("nodes", this.nodes);
}
}

View File

@@ -0,0 +1,193 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.fileplans;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.query.PagingResults;
import org.alfresco.repo.node.getchildren.FilterProp;
import org.alfresco.rest.api.impl.Util;
import org.alfresco.rest.api.model.UserInfo;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.impl.SearchTypesFactory;
import org.alfresco.rm.rest.api.model.FilePlan;
import org.alfresco.rm.rest.api.model.RecordCategory;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.springframework.beans.factory.InitializingBean;
/**
* File plan children relation
*
* @author Ramona Popa
* @since 2.6
*/
@RelationshipResource(name="categories", entityResource = FilePlanEntityResource.class, title = "Category children of file plan")
public class FilePlanChildrenRelation implements RelationshipResourceAction.Read<RecordCategory>,
RelationshipResourceAction.Create<RecordCategory>, InitializingBean
{
/** Record category type */
public static final String RECORD_CATEGORY_TYPE = "rma:recordCategory";
private FilePlanComponentsApiUtils apiUtils;
private FileFolderService fileFolderService;
private ApiNodesModelFactory nodesModelFactory;
private SearchTypesFactory searchTypesFactory;
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
public void setSearchTypesFactory(SearchTypesFactory searchTypesFactory)
{
this.searchTypesFactory = searchTypesFactory;
}
@Override
public void afterPropertiesSet() throws Exception
{
ParameterCheck.mandatory("apiUtils", this.apiUtils);
ParameterCheck.mandatory("fileFolderService", this.fileFolderService);
ParameterCheck.mandatory("nodesModelFactory", this.nodesModelFactory);
ParameterCheck.mandatory("searchTypesFactory", this.searchTypesFactory);
}
@Override
@WebApiDescription(title = "Return a paged list of file plan children (record categories) for the container identified by 'filePlanId'")
public CollectionWithPagingInfo<RecordCategory> readAll(String filePlanId, Parameters parameters)
{
// validate parameters
checkNotBlank("filePlanId", filePlanId);
mandatory("parameters", parameters);
QName filePlanType = apiUtils.getFilePlanType();
if(filePlanType == null)// rm site not created
{
throw new EntityNotFoundException(filePlanId);
}
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, filePlanType);
// list record categories
Set<QName> searchTypeQNames = searchTypesFactory.buildSearchTypesForFilePlanEndpoint();
//FIXME this param null
List<FilterProp> filterProps = apiUtils.getListChildrenFilterProps(parameters, null);
final PagingResults<FileInfo> pagingResults = fileFolderService.list(parentNodeRef,
null,
searchTypeQNames,
null,
apiUtils.getSortProperties(parameters),
filterProps,
Util.getPagingRequest(parameters.getPaging()));
final List<FileInfo> page = pagingResults.getPage();
Map<String, UserInfo> mapUserInfo = new HashMap<>();
List<RecordCategory> nodes = new AbstractList<RecordCategory>()
{
@Override
public RecordCategory get(int index)
{
FileInfo info = page.get(index);
return nodesModelFactory.createRecordCategory(info, parameters, mapUserInfo, true);
}
@Override
public int size()
{
return page.size();
}
};
FilePlan sourceEntity = null;
if (parameters.includeSource())
{
FileInfo info = fileFolderService.getFileInfo(parentNodeRef);
sourceEntity = nodesModelFactory.createFilePlan(info, parameters, mapUserInfo, true);
}
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), nodes, pagingResults.hasMoreItems(),
pagingResults.getTotalResultCount().getFirst(), sourceEntity);
}
@Override
@WebApiDescription(title="Create one (or more) record categories as children of container identified by 'filePlanId'")
public List<RecordCategory> create(String filePlanId, List<RecordCategory> nodeInfos, Parameters parameters)
{
checkNotBlank("filePlanId", filePlanId);
mandatory("nodeInfos", nodeInfos);
mandatory("parameters", parameters);
QName filePlanType = apiUtils.getFilePlanType();
if(filePlanType == null)// rm site not created
{
throw new EntityNotFoundException(filePlanId);
}
NodeRef parentNodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, filePlanType);
List<RecordCategory> result = new ArrayList<>(nodeInfos.size());
Map<String, UserInfo> mapUserInfo = new HashMap<>();
for (RecordCategory nodeInfo : nodeInfos)
{
// Create the node
NodeRef newNode = apiUtils.createRMNode(parentNodeRef, nodeInfo.getName(), RECORD_CATEGORY_TYPE, nodeInfo.getProperties(), nodeInfo.getAspectNames());
FileInfo info = fileFolderService.getFileInfo(newNode);
result.add(nodesModelFactory.createRecordCategory(info, parameters, mapUserInfo, false));
}
return result;
}
}

View File

@@ -0,0 +1,125 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.fileplans;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.impl.FilePlanComponentsApiUtils;
import org.alfresco.rm.rest.api.model.FilePlan;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.springframework.beans.factory.InitializingBean;
/**
* File plan entity resource
*
* @author Ramona Popa
* @since 2.6
*/
@EntityResource(name = "file-plans", title = "File plans")
public class FilePlanEntityResource
implements EntityResourceAction.ReadById<FilePlan>, EntityResourceAction.Update<FilePlan>, InitializingBean
{
private FilePlanComponentsApiUtils apiUtils;
private FileFolderService fileFolderService;
private ApiNodesModelFactory nodesModelFactory;
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
@Override
public void afterPropertiesSet() throws Exception
{
ParameterCheck.mandatory("apiUtils", this.apiUtils);
ParameterCheck.mandatory("fileFolderService", this.fileFolderService);
ParameterCheck.mandatory("nodesModelFactory", this.nodesModelFactory);
}
@WebApiDescription(title = "Get file plan information", description = "Get information for a file plan with id 'filePlanId'")
@WebApiParam(name = "filePlanId", title = "The file plan id")
public FilePlan readById(String filePlanId, Parameters parameters)
{
checkNotBlank("filePlanId", filePlanId);
mandatory("parameters", parameters);
QName filePlanType = apiUtils.getFilePlanType();
if(filePlanType == null)// rm site not created
{
throw new EntityNotFoundException(filePlanId);
}
NodeRef nodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, filePlanType);
FileInfo info = fileFolderService.getFileInfo(nodeRef);
return nodesModelFactory.createFilePlan(info, parameters, null, false);
}
@Override
@WebApiDescription(title = "Update file plan", description = "Updates a filePlan with id 'filePlanId'")
public FilePlan update(String filePlanId, FilePlan filePlanInfo, Parameters parameters)
{
checkNotBlank("filePlanId", filePlanId);
mandatory("filePlanInfo", filePlanInfo);
mandatory("parameters", parameters);
QName filePlanType = apiUtils.getFilePlanType();
if(filePlanType == null)// rm site not created
{
throw new EntityNotFoundException(filePlanId);
}
NodeRef nodeRef = apiUtils.lookupAndValidateNodeType(filePlanId, filePlanType);
apiUtils.updateNode(nodeRef, filePlanInfo, parameters);
FileInfo info = fileFolderService.getFileInfo(nodeRef);
return nodesModelFactory.createFilePlan(info, parameters, null, false);
}
}

View File

@@ -0,0 +1,37 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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 info that defines the Information Governance File Plans REST API
*
* @author Ramona Popa
* @since 2.6
*/
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
package org.alfresco.rm.rest.api.fileplans;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.WebApi;

View File

@@ -27,14 +27,21 @@
package org.alfresco.rm.rest.api.files;
import org.alfresco.rest.api.model.Node;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.rest.framework.Operation;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.resource.EntityResource;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.webscripts.WithResponse;
import org.alfresco.rm.rest.api.Records;
import org.alfresco.rm.rest.api.model.TargetContainer;
import org.alfresco.rm.rest.api.impl.ApiNodesModelFactory;
import org.alfresco.rm.rest.api.model.Record;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.util.ParameterCheck;
import org.springframework.beans.factory.InitializingBean;
@@ -47,23 +54,70 @@ import org.springframework.beans.factory.InitializingBean;
@EntityResource(name="files", title = "Files")
public class FilesEntityResource implements InitializingBean
{
private Records records;
private ApiNodesModelFactory nodesModelFactory;
private AuthenticationUtil authenticationUtil;
private FilePlanService filePlanService;
private FileFolderService fileFolderService;
private RecordService recordService;
public void setRecords(Records records)
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
{
this.records = records;
this.authenticationUtil = authenticationUtil;
}
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
public void setNodesModelFactory(ApiNodesModelFactory nodesModelFactory)
{
this.nodesModelFactory = nodesModelFactory;
}
@Operation("declare")
@WebApiDescription(title = "Declare as record", description="Declare a file as record.")
public Node declareAsRecord(String fileId, Void body, Parameters parameters, WithResponse withResponse)
public Record declareAsRecord(String fileId, Void body, Parameters parameters, WithResponse withResponse)
{
return records.declareFileAsRecord(fileId, parameters);
// Get fileplan
NodeRef filePlan = authenticationUtil.runAsSystem(new RunAsWork<NodeRef>()
{
@Override
public NodeRef doWork()
{
return filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
}
});
// default false (if not provided)
boolean hideRecord = Boolean.valueOf(parameters.getParameter(Record.PARAM_HIDE_RECORD));
// Create the record
NodeRef file = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, fileId);
recordService.createRecord(filePlan, file, !hideRecord);
// Return record state
FileInfo info = fileFolderService.getFileInfo(file);
return nodesModelFactory.createRecord(info, parameters, null, false);
}
@Override
public void afterPropertiesSet() throws Exception
{
ParameterCheck.mandatory("records", this.records);
ParameterCheck.mandatory("nodesModelFactory", nodesModelFactory);
ParameterCheck.mandatory("authenticationUtil", authenticationUtil);
ParameterCheck.mandatory("filePlanService", filePlanService);
ParameterCheck.mandatory("fileFolderService", fileFolderService);
ParameterCheck.mandatory("recordService", recordService);
}
}

View File

@@ -27,11 +27,11 @@
/**
* Package info that defines the Information Governance Files REST API
*
*
* @author Ana Bozianu
* @since 2.6
*/
@WebApi(name="ig", scope=Api.SCOPE.PUBLIC, version=1)
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
package org.alfresco.rm.rest.api.files;
import org.alfresco.rest.framework.Api;
import org.alfresco.rest.framework.WebApi;

View File

@@ -0,0 +1,839 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.model.ContentModel;
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.rest.api.Nodes;
import org.alfresco.rest.api.model.ContentInfo;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.api.model.UserInfo;
import org.alfresco.rest.framework.jacksonextensions.BeanPropertiesFilter;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.model.FilePlan;
import org.alfresco.rm.rest.api.model.RMNode;
import org.alfresco.rm.rest.api.model.Record;
import org.alfresco.rm.rest.api.model.RecordCategory;
import org.alfresco.rm.rest.api.model.RecordCategoryChild;
import org.alfresco.rm.rest.api.model.RecordFolder;
import org.alfresco.rm.rest.api.model.Transfer;
import org.alfresco.rm.rest.api.model.TransferChild;
import org.alfresco.rm.rest.api.model.TransferContainer;
import org.alfresco.rm.rest.api.model.UnfiledChild;
import org.alfresco.rm.rest.api.model.UnfiledContainer;
import org.alfresco.rm.rest.api.model.UnfiledContainerChild;
import org.alfresco.rm.rest.api.model.UnfiledRecordFolder;
import org.alfresco.rm.rest.api.model.UnfiledRecordFolderChild;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* Utility class containing Alfresco and RM java services required by the API
* endpoints
*
* @author Ana Bozianu
* @since 2.6
*/
public class ApiNodesModelFactory
{
// excluded namespaces (aspects, properties, assoc types)
public static final List<String> EXCLUDED_NS = Arrays.asList(NamespaceService.SYSTEM_MODEL_1_0_URI);
// excluded aspects
public static final List<QName> EXCLUDED_ASPECTS = Arrays.asList();
// excluded properties
public static final List<QName> EXCLUDED_PROPS = Arrays.asList(
// top-level minimal info
ContentModel.PROP_NAME, ContentModel.PROP_MODIFIER, ContentModel.PROP_MODIFIED, ContentModel.PROP_CREATOR,
ContentModel.PROP_CREATED, ContentModel.PROP_CONTENT,
// other - TBC
ContentModel.PROP_INITIAL_VERSION, ContentModel.PROP_AUTO_VERSION_PROPS, ContentModel.PROP_AUTO_VERSION);
private NodeService nodeService;
private NamespaceService namespaceService;
private Nodes nodes;
private FilePlanComponentsApiUtils apiUtils;
private PersonService personService;
private DispositionService dispositionService;
private ServiceRegistry serviceRegistry;
public NodeService getNodeService()
{
return nodeService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public NamespaceService getNamespaceService()
{
return namespaceService;
}
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setApiUtils(FilePlanComponentsApiUtils apiUtils)
{
this.apiUtils = apiUtils;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public DispositionService getDispositionService()
{
return dispositionService;
}
public void setDispositionService(DispositionService dispositionService)
{
this.dispositionService = dispositionService;
}
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
/**
* Helper method that sets the basic information for most of the node types.
*
* @param rmNode
* @param info
* @param propertyFilter
* @param isMinimalInfo
*/
private void mapBasicInfo(RMNode rmNode, FileInfo info, BeanPropertiesFilter propertyFilter, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
if (propertyFilter.isAllowed(RMNode.PARAM_ID))
{
rmNode.setNodeRef(info.getNodeRef());
}
if (propertyFilter.isAllowed(RMNode.PARAM_PARENT_ID))
{
rmNode.setParentId(nodeService.getPrimaryParent(info.getNodeRef()).getParentRef());
}
if (propertyFilter.isAllowed(RMNode.PARAM_NAME))
{
rmNode.setName(info.getName());
}
if (propertyFilter.isAllowed(RMNode.PARAM_NODE_TYPE))
{
rmNode.setNodeType(info.getType().toPrefixString(namespaceService));
}
if (propertyFilter.isAllowed(RMNode.PARAM_MODIFIED_AT))
{
rmNode.setModifiedAt(info.getModifiedDate());
}
if (propertyFilter.isAllowed(RMNode.PARAM_MODIFIED_BY_USER))
{
if (mapUserInfo == null)
{
mapUserInfo = new HashMap<>(2);
}
UserInfo modifer = Node.lookupUserInfo((String) info.getProperties().get(ContentModel.PROP_MODIFIER), mapUserInfo,
personService);
rmNode.setModifiedByUser(modifer);
}
if (propertyFilter.isAllowed(RMNode.PARAM_CREATED_AT))
{
rmNode.setCreatedAt(info.getCreatedDate());
}
if (propertyFilter.isAllowed(RMNode.PARAM_CREATED_BY_USER))
{
if (mapUserInfo == null)
{
mapUserInfo = new HashMap<>(2);
}
UserInfo creator = Node.lookupUserInfo((String) info.getProperties().get(ContentModel.PROP_CREATOR), mapUserInfo,
personService);
rmNode.setCreatedByUser(creator);
}
if (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_ASPECT_NAMES))
{
rmNode.setAspectNames(mapFromNodeAspects(nodeService.getAspects(info.getNodeRef())));
}
if (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_PROPERTIES))
{
rmNode.setProperties(mapFromNodeProperties(info.getProperties()));
}
}
/**
* Helper method that sets the optional information for most of the node types.
*
* @param rmNode
* @param info
* @param includeParam
* @param isMinimalInfo
*/
private void mapOptionalInfo(RMNode rmNode, FileInfo info, List<String> includeParam, boolean isMinimalInfo)
{
if (includeParam == null || includeParam.isEmpty())
{
return;
}
if (includeParam.contains(RMNode.PARAM_ALLOWABLE_OPERATIONS))
{
rmNode.setAllowableOperations(apiUtils.getAllowableOperations(info.getNodeRef(), info.getType()));
}
if (includeParam.contains(RMNode.PARAM_PATH))
{
rmNode.setPath(apiUtils.lookupPathInfo(info.getNodeRef()));
}
if (isMinimalInfo && includeParam.contains(RMNode.PARAM_ASPECT_NAMES))
{
rmNode.setAspectNames(mapFromNodeAspects(nodeService.getAspects(info.getNodeRef())));
}
if (isMinimalInfo && includeParam.contains(RMNode.PARAM_PROPERTIES))
{
rmNode.setProperties(mapFromNodeProperties(info.getProperties()));
}
}
/**
* Helper method that sets the information for unfiled child type.
*
* @param unfiledChild
* @param info
* @param propertyFilter
*/
private void mapUnfiledChildInfo(UnfiledChild unfiledChild, FileInfo info, BeanPropertiesFilter propertyFilter)
{
if (RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER.equals(info.getType()))
{
if (propertyFilter.isAllowed(UnfiledChild.PARAM_IS_UNFILED_RECORD_FOLDER))
{
unfiledChild.setIsUnfiledRecordFolder(true);
}
if (propertyFilter.isAllowed(UnfiledChild.PARAM_IS_RECORD))
{
unfiledChild.setIsRecord(false);
}
}
else
{
if (propertyFilter.isAllowed(UnfiledChild.PARAM_IS_UNFILED_RECORD_FOLDER))
{
unfiledChild.setIsUnfiledRecordFolder(false);
}
if (propertyFilter.isAllowed(UnfiledChild.PARAM_IS_RECORD))
{
unfiledChild.setIsRecord(true);
}
}
}
/**
* Helper method that sets the information for transfer container type.
*
* @param transferContainer
* @param info
* @param propertyFilter
*/
private void mapTransferContainerInfo(TransferContainer transferContainer, FileInfo info, Map<String, UserInfo> mapUserInfo, BeanPropertiesFilter propertyFilter, List<String> includeParam, boolean isMinimalInfo)
{
if (propertyFilter.isAllowed(RMNode.PARAM_ID))
{
transferContainer.setNodeRef(info.getNodeRef());
}
if (propertyFilter.isAllowed(RMNode.PARAM_PARENT_ID))
{
transferContainer.setParentId(nodeService.getPrimaryParent(info.getNodeRef()).getParentRef());
}
if (propertyFilter.isAllowed(RMNode.PARAM_NAME))
{
transferContainer.setName(info.getName());
}
if (propertyFilter.isAllowed(RMNode.PARAM_NODE_TYPE))
{
transferContainer.setNodeType(info.getType().toPrefixString(namespaceService));
}
if (propertyFilter.isAllowed(RMNode.PARAM_MODIFIED_AT))
{
transferContainer.setModifiedAt(info.getModifiedDate());
}
if (propertyFilter.isAllowed(RMNode.PARAM_MODIFIED_BY_USER))
{
if (mapUserInfo == null)
{
mapUserInfo = new HashMap<>(2);
}
UserInfo modifer = Node.lookupUserInfo((String) info.getProperties().get(ContentModel.PROP_MODIFIER), mapUserInfo,
personService);
transferContainer.setModifiedByUser(modifer);
}
if (propertyFilter.isAllowed(RMNode.PARAM_CREATED_AT))
{
transferContainer.setCreatedAt(info.getCreatedDate());
}
if (propertyFilter.isAllowed(RMNode.PARAM_CREATED_BY_USER))
{
if (mapUserInfo == null)
{
mapUserInfo = new HashMap<>(2);
}
UserInfo creator = Node.lookupUserInfo((String) info.getProperties().get(ContentModel.PROP_CREATOR), mapUserInfo,
personService);
transferContainer.setCreatedByUser(creator);
}
if (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_ASPECT_NAMES))
{
transferContainer.setAspectNames(mapFromNodeAspects(nodeService.getAspects(info.getNodeRef())));
}
if (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_PROPERTIES))
{
transferContainer.setProperties(mapFromNodeProperties(info.getProperties()));
}
//optional parameters
if (includeParam == null || includeParam.isEmpty())
{
return;
}
if (includeParam.contains(RMNode.PARAM_ALLOWABLE_OPERATIONS))
{
transferContainer.setAllowableOperations(apiUtils.getAllowableOperations(info.getNodeRef(), info.getType()));
}
if (isMinimalInfo && includeParam.contains(RMNode.PARAM_ASPECT_NAMES))
{
transferContainer.setAspectNames(mapFromNodeAspects(nodeService.getAspects(info.getNodeRef())));
}
if (isMinimalInfo && includeParam.contains(RMNode.PARAM_PROPERTIES))
{
transferContainer.setProperties(mapFromNodeProperties(info.getProperties()));
}
}
/**
* Helper method that sets the information for transfer type.
*
* @param transfer
* @param info
* @param propertyFilter
*/
private void mapTransferInfo(Transfer transfer, FileInfo info, Map<String, UserInfo> mapUserInfo, BeanPropertiesFilter propertyFilter, List<String> includeParam, boolean isMinimalInfo)
{
if (propertyFilter.isAllowed(RMNode.PARAM_ID))
{
transfer.setNodeRef(info.getNodeRef());
}
if (propertyFilter.isAllowed(RMNode.PARAM_PARENT_ID))
{
transfer.setParentId(nodeService.getPrimaryParent(info.getNodeRef()).getParentRef());
}
if (propertyFilter.isAllowed(RMNode.PARAM_NAME))
{
transfer.setName(info.getName());
}
if (propertyFilter.isAllowed(RMNode.PARAM_NODE_TYPE))
{
transfer.setNodeType(info.getType().toPrefixString(namespaceService));
}
if (propertyFilter.isAllowed(RMNode.PARAM_CREATED_AT))
{
transfer.setCreatedAt(info.getCreatedDate());
}
if (propertyFilter.isAllowed(RMNode.PARAM_CREATED_BY_USER))
{
if (mapUserInfo == null)
{
mapUserInfo = new HashMap<>(2);
}
UserInfo creator = Node.lookupUserInfo((String) info.getProperties().get(ContentModel.PROP_CREATOR), mapUserInfo,
personService);
transfer.setCreatedByUser(creator);
}
if (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_ASPECT_NAMES))
{
transfer.setAspectNames(mapFromNodeAspects(nodeService.getAspects(info.getNodeRef())));
}
if (!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_PROPERTIES))
{
transfer.setProperties(mapFromNodeProperties(info.getProperties()));
}
//optional parameters
if (isMinimalInfo && includeParam == null || includeParam.isEmpty())
{
return;
}
if (includeParam.contains(RMNode.PARAM_ALLOWABLE_OPERATIONS))
{
transfer.setAllowableOperations(apiUtils.getAllowableOperations(info.getNodeRef(), info.getType()));
}
if (isMinimalInfo && includeParam.contains(RMNode.PARAM_ASPECT_NAMES))
{
transfer.setAspectNames(mapFromNodeAspects(nodeService.getAspects(info.getNodeRef())));
}
if (isMinimalInfo && includeParam.contains(RMNode.PARAM_PROPERTIES))
{
transfer.setProperties(mapFromNodeProperties(info.getProperties()));
}
if ((!isMinimalInfo && propertyFilter.isAllowed(Transfer.PARAM_TRANSFER_ACCESSION_INDICATOR)) || (isMinimalInfo && includeParam.contains(Transfer.PARAM_TRANSFER_ACCESSION_INDICATOR)))
{
transfer.setTransferAccessionIndicator((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_TRANSFER_ACCESSION_INDICATOR));
}
if ((!isMinimalInfo && propertyFilter.isAllowed(Transfer.PARAM_TRANSFER_LOCATION)) || (isMinimalInfo && includeParam.contains(Transfer.PARAM_TRANSFER_LOCATION)))
{
transfer.setTransferLocation((String) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_TRANSFER_LOCATION));
}
if ((!isMinimalInfo && propertyFilter.isAllowed(Transfer.PARAM_TRANSFER_PDF_INDICATOR)) || (isMinimalInfo && includeParam.contains(Transfer.PARAM_TRANSFER_PDF_INDICATOR)))
{
transfer.setTransferPDFIndicator((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_TRANSFER_PDF_INDICATOR));
}
}
/**
* Helper method that sets the information for transfer child type.
*
* @param transferChild
* @param info
* @param propertyFilter
*/
private void mapTransferChildInfo(TransferChild transferChild, FileInfo info, List<String> includeParam, boolean isMinimalInfo)
{
if (includeParam == null || includeParam.isEmpty())
{
return;
}
if (RecordsManagementModel.TYPE_RECORD_FOLDER.equals(info.getType()))
{
if (isMinimalInfo && includeParam.contains(TransferChild.PARAM_IS_RECORD_FOLDER))
{
transferChild.setIsRecordFolder(true);
}
if (isMinimalInfo && includeParam.contains(TransferChild.PARAM_IS_RECORD))
{
transferChild.setIsRecord(false);
}
if(isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED))
{
transferChild.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
}
if(isMinimalInfo && includeParam.contains(TransferChild.PARAM_IS_COMPLETED))
{
transferChild.setIsCompleted(null);
}
}
else
{
if (isMinimalInfo && includeParam.contains(TransferChild.PARAM_IS_RECORD_FOLDER))
{
transferChild.setIsRecordFolder(false);
}
if (isMinimalInfo && includeParam.contains(TransferChild.PARAM_IS_RECORD))
{
transferChild.setIsRecord(true);
}
if(isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED))
{
transferChild.setIsClosed(null);
}
if(isMinimalInfo && includeParam.contains(TransferChild.PARAM_IS_COMPLETED))
{
transferChild.setIsCompleted(nodeService.hasAspect(info.getNodeRef(), RecordsManagementModel.ASPECT_DECLARED_RECORD));
}
}
}
/**
* Helper method that sets the information for record category child type.
*
* @param recordCategoryChild the record category child to set the fields to
* @param info info of the record category child
* @param includeParam the requested include parameters
* @param propertyFilter
*/
private void mapRecordCategoryChildInfo(RecordCategoryChild recordCategoryChild, FileInfo info, List<String> includeParam, BeanPropertiesFilter propertyFilter, boolean isMinimalInfo)
{
if (isMinimalInfo && (includeParam == null || includeParam.isEmpty()))
{
return;
}
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(info.getType()))
{
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
{
recordCategoryChild.setIsRecordFolder(true);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
{
recordCategoryChild.setIsRecordCategory(false);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
{
recordCategoryChild.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
}
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_HAS_RETENTION_SCHEDULE)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_HAS_RETENTION_SCHEDULE)))
{
recordCategoryChild.setHasRetentionSchedule(null);
}
}
else
{
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_FOLDER)))
{
recordCategoryChild.setIsRecordFolder(false);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)) || (isMinimalInfo && includeParam.contains(RecordCategoryChild.PARAM_IS_RECORD_CATEGORY)))
{
recordCategoryChild.setIsRecordCategory(true);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_HAS_RETENTION_SCHEDULE)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_HAS_RETENTION_SCHEDULE)))
{
DispositionSchedule ds = dispositionService.getDispositionSchedule(info.getNodeRef());
recordCategoryChild.setHasRetentionSchedule(ds !=null ? true : false);
}
if((!isMinimalInfo && propertyFilter.isAllowed(RMNode.PARAM_IS_CLOSED)) || (isMinimalInfo && includeParam.contains(RMNode.PARAM_IS_CLOSED)))
{
recordCategoryChild.setIsClosed(null);
}
}
}
/**
* Utility method that maps record specific fields
*
* @param record the record to set the fields to
* @param info info of the record
* @param includeParam the requested include parameters
*/
private void mapRecordInfo(Record record, FileInfo info, List<String> includeParam)
{
if (includeParam == null || includeParam.isEmpty())
{
return;
}
if (includeParam.contains(Record.PARAM_IS_COMPLETED))
{
record.setIsCompleted(nodeService.hasAspect(info.getNodeRef(), RecordsManagementModel.ASPECT_DECLARED_RECORD));
}
if(includeParam.contains(Record.PARAM_CONTENT))
{
Serializable val = info.getProperties().get(ContentModel.PROP_CONTENT);
if ((val != null) && (val instanceof ContentData)) {
ContentData cd = (ContentData)val;
String mimeType = cd.getMimetype();
String mimeTypeName = serviceRegistry.getMimetypeService().getDisplaysByMimetype().get(mimeType);
ContentInfo contentInfo = new ContentInfo(mimeType, mimeTypeName, cd.getSize(), cd.getEncoding());
record.setContent(contentInfo);
}
}
}
/**
* Helper method that converts a set of QName aspects into a list of String aspects
*
* @param properties
*/
private List<String> mapFromNodeAspects(Set<QName> nodeAspects)
{
return nodes.mapFromNodeAspects(nodeAspects, EXCLUDED_NS, EXCLUDED_ASPECTS);
}
/**
* Helper method that converts a map of QName properties into a map of String properties
*
* @param properties
* @return a map of String properties
*/
private Map<String, Object> mapFromNodeProperties(Map<QName, Serializable> properties)
{
return nodes.mapFromNodeProperties(properties, new ArrayList<>(), new HashMap<>(), EXCLUDED_NS, EXCLUDED_PROPS);
}
/**
* Creates an object of type FilePlan
*
* @param info info of the file plan
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return FilePlan object
*/
public FilePlan createFilePlan(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo, boolean isMinimalInfo)
{
FilePlan filePlan = new FilePlan();
mapBasicInfo(filePlan, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(filePlan, info, parameters.getInclude(), isMinimalInfo);
return filePlan;
}
/**
* Creates an object of type RecordCategory
*
* @param info info of the record category
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return RecordCategory object
*/
public RecordCategory createRecordCategory(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
RecordCategory recordCategory = new RecordCategory();
mapBasicInfo(recordCategory, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(recordCategory, info, parameters.getInclude(), isMinimalInfo);
if (parameters.getInclude().contains(RMNode.PARAM_HAS_RETENTION_SCHEDULE))
{
DispositionSchedule ds = dispositionService.getDispositionSchedule(info.getNodeRef());
recordCategory.setHasRetentionSchedule(ds !=null ? true : false);
}
return recordCategory;
}
/**
* Creates an object of type RecordCategory
*
* @param info
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return RecordCategory object
*/
public RecordFolder createRecordFolder(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
RecordFolder recordFolder = new RecordFolder();
mapBasicInfo(recordFolder, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(recordFolder, info, parameters.getInclude(), isMinimalInfo);
if (parameters.getInclude().contains(RMNode.PARAM_IS_CLOSED))
{
recordFolder.setIsClosed((Boolean) nodeService.getProperty(info.getNodeRef(), RecordsManagementModel.PROP_IS_CLOSED));
}
return recordFolder;
}
/**
* Creates an object of type UnfiledContainer
*
* @param info
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledContainer object
*/
public UnfiledContainer createUnfiledContainer(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
UnfiledContainer unfiledContainer = new UnfiledContainer();
mapBasicInfo(unfiledContainer, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(unfiledContainer, info, parameters.getInclude(), isMinimalInfo);
return unfiledContainer;
}
/**
* Creates an object of type TransferContainer
*
* @param info
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledContainer object
*/
public TransferContainer createTransferContainer(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
TransferContainer transferContainer = new TransferContainer();
mapTransferContainerInfo(transferContainer, info, mapUserInfo, parameters.getFilter(), parameters.getInclude(), isMinimalInfo);
return transferContainer;
}
/**
* Creates an object of type Transfer
*
* @param info
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledContainer object
*/
public Transfer createTransfer(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
Transfer transfer = new Transfer();
mapTransferInfo(transfer, info, mapUserInfo, parameters.getFilter(), parameters.getInclude(), isMinimalInfo);
return transfer;
}
/**
* Creates an object of type TransferChild
*
* @param info
* @param propertyFilter
* @param includeParam
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledContainer object
*/
public TransferChild createTransferChild(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
TransferChild transferChild = new TransferChild();
mapBasicInfo(transferChild, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(transferChild, info, parameters.getInclude(), isMinimalInfo);
mapTransferChildInfo(transferChild, info, parameters.getInclude(), isMinimalInfo);
return transferChild;
}
/**
* Creates an object of type UnfiledContainerChild
*
* @param info
* @param parameters
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledContainerChild object
*/
public UnfiledContainerChild createUnfiledContainerChild(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
UnfiledContainerChild unfiledContainerChild = new UnfiledContainerChild();
mapBasicInfo(unfiledContainerChild, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(unfiledContainerChild, info, parameters.getInclude(), isMinimalInfo);
mapUnfiledChildInfo(unfiledContainerChild, info, parameters.getFilter());
return unfiledContainerChild;
}
/**
* Creates an object of type UnfiledRecordFolder
*
* @param info
* @param parameters
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledRecordFolder object
*/
public UnfiledRecordFolder createUnfiledRecordFolder(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
UnfiledRecordFolder unfiledChild = new UnfiledRecordFolder();
mapBasicInfo(unfiledChild, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(unfiledChild, info, parameters.getInclude(), isMinimalInfo);
return unfiledChild;
}
/**
* Creates an object of type UnfiledRecordFolderChild
*
* @param info
* @param parameters
* @param mapUserInfo
* @param isMinimalInfo
* @return UnfiledRecordFolderChild object
*/
public UnfiledRecordFolderChild createUnfiledRecordFolderChild(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
UnfiledRecordFolderChild unfiledRecordFolderChild = new UnfiledRecordFolderChild();
mapBasicInfo(unfiledRecordFolderChild, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(unfiledRecordFolderChild, info, parameters.getInclude(), isMinimalInfo);
mapUnfiledChildInfo(unfiledRecordFolderChild, info, parameters.getFilter());
return unfiledRecordFolderChild;
}
/**
* Creates an object of type RecordCategoryChild
*
* @param info
* @param parameters
* @param mapUserInfo
* @param isMinimalInfo
* @return
*/
public RecordCategoryChild createRecordCategoryChild(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo,
boolean isMinimalInfo)
{
RecordCategoryChild recordCategoryChild = new RecordCategoryChild();
mapBasicInfo(recordCategoryChild, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(recordCategoryChild, info, parameters.getInclude(), isMinimalInfo);
mapRecordCategoryChildInfo(recordCategoryChild, info, parameters.getInclude(), parameters.getFilter(), isMinimalInfo);
return recordCategoryChild;
}
/**
* Create an object of type Record
*
* @param info
* @param parameters
* @param mapUserInfo
* @param isMinimalInfo
* @return
*/
public Record createRecord(FileInfo info, Parameters parameters, Map<String, UserInfo> mapUserInfo, boolean isMinimalInfo)
{
Record record = new Record();
mapBasicInfo(record, info, parameters.getFilter(), mapUserInfo, isMinimalInfo);
mapOptionalInfo(record, info, parameters.getInclude(), isMinimalInfo);
mapRecordInfo(record, info, parameters.getInclude());
return record;
}
}

View File

@@ -0,0 +1,961 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.impl;
import static org.alfresco.module.org_alfresco_module_rm.util.RMParameterCheck.checkNotBlank;
import static org.alfresco.util.ParameterCheck.mandatory;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
import org.alfresco.repo.content.ContentLimitViolationException;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl.InvalidTypeException;
import org.alfresco.repo.node.getchildren.FilterProp;
import org.alfresco.repo.node.getchildren.FilterPropBoolean;
import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.tenant.TenantUtil;
import org.alfresco.rest.antlr.WhereClauseParser;
import org.alfresco.rest.api.Activities;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.PathInfo;
import org.alfresco.rest.api.model.PathInfo.ElementInfo;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InsufficientStorageException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
import org.alfresco.rest.framework.core.exceptions.RequestEntityTooLargeException;
import org.alfresco.rest.framework.resource.content.BinaryResource;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rest.framework.resource.parameters.where.Query;
import org.alfresco.rest.framework.resource.parameters.where.QueryHelper;
import org.alfresco.rest.workflow.api.impl.MapBasedQueryWalker;
import org.alfresco.rm.rest.api.RMSites;
import org.alfresco.rm.rest.api.model.RMNode;
import org.alfresco.rm.rest.api.model.RMSite;
import org.alfresco.rm.rest.api.model.TransferContainer;
import org.alfresco.service.cmr.activities.ActivityInfo;
import org.alfresco.service.cmr.activities.ActivityPoster;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.lock.NodeLockedException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.Path.Element;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.social.InternalServerErrorException;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
/**
* Utility class that handles common api endpoint tasks
*
* @author Ana Bozianu
* @since 2.6
*/
public class FilePlanComponentsApiUtils
{
private static final Logger LOGGER = LoggerFactory.getLogger(SearchTypesFactory.class);
public static final String FILE_PLAN_ALIAS = "-filePlan-";
public static final String TRANSFERS_ALIAS = "-transfers-";
public static final String UNFILED_ALIAS = "-unfiled-";
public static final String HOLDS_ALIAS = "-holds-";
public static final String RM_SITE_ID = "rm";
//public static String PARAM_RELATIVE_PATH = "relativePath";
// excluded properties
public static final List<QName> TYPES_CAN_CREATE = Arrays.asList(
RecordsManagementModel.TYPE_FILE_PLAN,
RecordsManagementModel.TYPE_RECORD_CATEGORY,
RecordsManagementModel.TYPE_RECORD_FOLDER,
RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER,
RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER,
RecordsManagementModel.TYPE_HOLD_CONTAINER);
/** RM Nodes API */
private Nodes nodes;
private FileFolderService fileFolderService;
private FilePlanService filePlanService;
private NodeService nodeService;
private ContentService contentService;
private MimetypeService mimetypeService;
private DictionaryService dictionaryService;
private CapabilityService capabilityService;
private PermissionService permissionService;
private RecordService recordService;
private AuthenticationUtil authenticationUtil;
private ActivityPoster activityPoster;
private RMSites sites;
public void setNodes(Nodes nodes)
{
this.nodes = nodes;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
public void setCapabilityService(CapabilityService capabilityService)
{
this.capabilityService = capabilityService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setRecordService(RecordService recordService)
{
this.recordService = recordService;
}
public void setAuthenticationUtil(AuthenticationUtil authenticationUtil)
{
this.authenticationUtil = authenticationUtil;
}
public void setActivityPoster(ActivityPoster poster)
{
this.activityPoster = poster;
}
public void setSites(RMSites sites)
{
this.sites = sites;
}
/**
* lookup node and validate type
*
* @param nodeId
* @param expectedNodeType
* @return
* @throws EntityNotFoundException
*/
public NodeRef lookupAndValidateNodeType(String nodeId, QName expectedNodeType) throws EntityNotFoundException
{
return lookupAndValidateNodeType(nodeId, expectedNodeType, null);
}
/**
* lookup node by id and relative path and validate type
*
* @param nodeId
* @param expectedNodeType
* @param relativePath
* @return
* @throws EntityNotFoundException
*/
public NodeRef lookupAndValidateNodeType(String nodeId, QName expectedNodeType, String relativePath) throws EntityNotFoundException
{
return lookupAndValidateNodeType(nodeId, expectedNodeType, relativePath, false);
}
/**
* lookup node by id and relative path and validate type
*
* @param nodeId
* @param expectedNodeType
* @param relativePath
* @return
* @throws EntityNotFoundException
*/
public NodeRef lookupAndValidateNodeType(String nodeId, QName expectedNodeType, String relativePath, boolean readOnlyRelativePath) throws EntityNotFoundException
{
ParameterCheck.mandatoryString("nodeId", nodeId);
ParameterCheck.mandatory("expectedNodeType", expectedNodeType);
/*
* Lookup by placeholder
*/
NodeRef nodeRef;
if (nodeId.equals(FILE_PLAN_ALIAS))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
nodeRef = filePlan;
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else if (nodeId.equals(TRANSFERS_ALIAS))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
nodeRef = filePlanService.getTransferContainer(filePlan);
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else if (nodeId.equals(UNFILED_ALIAS))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
nodeRef = filePlanService.getUnfiledContainer(filePlan);
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else if (nodeId.equals(HOLDS_ALIAS))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
nodeRef = filePlanService.getHoldContainer(filePlan);
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else
{
nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
}
QName nodeType = nodeService.getType(nodeRef);
if (!nodeType.equals(expectedNodeType))
{
throw new InvalidArgumentException("The given id:'" + nodeId + "' (nodeType:" + nodeType.toString()
+ ") is not valid for this endpoint. Expected nodeType is:" + expectedNodeType.toString());
}
if(StringUtils.isNotBlank(relativePath))
{
nodeRef = lookupAndValidateRelativePath(nodeRef, relativePath, readOnlyRelativePath, expectedNodeType);
}
return nodeRef;
}
/**
* TODO
* @param parameters
* @return
*/
public List<Pair<QName, Boolean>> getSortProperties(Parameters parameters)
{
List<Pair<QName, Boolean>> sortProps = new ArrayList<>();
sortProps.add(new Pair<>(GetChildrenCannedQuery.SORT_QNAME_NODE_TYPE, true));
sortProps.add(new Pair<>(ContentModel.PROP_NAME, true));
return sortProps;
}
/**
* Write content to file
*
* @param nodeRef the node to write the content to
* @param fileName the name of the file (used for guessing the file's mimetype)
* @param stream the input stream to write
* @param guessEncoding whether to guess stream encoding
*/
public void writeContent(NodeRef nodeRef, String fileName, InputStream stream, boolean guessEncoding)
{
try
{
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
String mimeType = mimetypeService.guessMimetype(fileName);
if ((mimeType != null) && (!mimeType.equals(MimetypeMap.MIMETYPE_BINARY)))
{
// quick/weak guess based on file extension
writer.setMimetype(mimeType);
} else
{
// stronger guess based on file stream
writer.guessMimetype(fileName);
}
InputStream is = null;
if (guessEncoding)
{
is = new BufferedInputStream(stream);
is.mark(1024);
writer.setEncoding(guessEncoding(is, mimeType, false));
try
{
is.reset();
} catch (IOException ioe)
{
if (LOGGER.isWarnEnabled())
{
LOGGER.warn("Failed to reset stream after trying to guess encoding: " + ioe.getMessage());
}
}
} else
{
is = stream;
}
writer.putContent(is);
}
catch (ContentQuotaException cqe)
{
throw new InsufficientStorageException();
}
catch (ContentLimitViolationException clv)
{
throw new RequestEntityTooLargeException(clv.getMessage());
}
catch (ContentIOException cioe)
{
if (cioe.getCause() instanceof NodeLockedException)
{
throw (NodeLockedException)cioe.getCause();
}
throw cioe;
}
}
/**
* Helper method that guesses the encoding of a stream of data
* @param in the stream to guess the encoding for
* @param mimeType the mimetype of the file
* @param close if true the stream will be closed at the end
* @return the stream encoding
*/
private String guessEncoding(InputStream in, String mimeType, boolean close)
{
String encoding = "UTF-8";
try
{
if (in != null)
{
Charset charset = mimetypeService.getContentCharsetFinder().getCharset(in, mimeType);
encoding = charset.name();
}
}
finally
{
try
{
if (close && (in != null))
{
in.close();
}
}
catch (IOException ioe)
{
if (LOGGER.isWarnEnabled())
{
LOGGER.warn("Failed to close stream after trying to guess encoding: " + ioe.getMessage());
}
}
}
return encoding;
}
/**
* Helper method that creates a relative path if it doesn't already exist
* The relative path will be build with nodes of the type specified in nodesType
* If the relative path already exists the method validates if the last element is of type nodesType
* The method does not validate the type of parentNodeRef
*
* @param parentNodeRef the first node of the path
* @param relativePath a string representing the relative path in the format "Folder1/Folder2/Folder3"
* @param nodesType the type of all the containers in the path
* @return the last element of the relative path
*/
public NodeRef lookupAndValidateRelativePath(final NodeRef parentNodeRef, String relativePath, QName nodesType)
{
return lookupAndValidateRelativePath(parentNodeRef, relativePath, false, nodesType);
}
/**
* Helper method that creates a relative path if it doesn't already exist and if relative path is not read only.
* If relative path is read only an exception will be thrown if the provided relative path does not exist.
* The relative path will be build with nodes of the type specified in nodesType
* If the relative path already exists the method validates if the last element is of type nodesType
* The method does not validate the type of parentNodeRef
*
* @param parentNodeRef the first node of the path
* @param relativePath a string representing the relative path in the format "Folder1/Folder2/Folder3"
* @param readOnlyRelativePath the flag that indicates if the relativePath should be created if doesn't exist or not
* @param nodesType the type of all the containers in the path
* @return the last element of the relative path
*/
public NodeRef lookupAndValidateRelativePath(final NodeRef parentNodeRef, String relativePath, boolean readOnlyRelativePath, QName nodesType)
{
mandatory("parentNodeRef", parentNodeRef);
mandatory("nodesType", nodesType);
if (StringUtils.isBlank(relativePath))
{
return parentNodeRef;
}
List<String> pathElements = getPathElements(relativePath);
if (pathElements.isEmpty())
{
return parentNodeRef;
}
/*
* Get the latest existing path element
*/
NodeRef lastNodeRef = parentNodeRef;
int i = 0;
for (; i < pathElements.size(); i++)
{
final String pathElement = pathElements.get(i);
final NodeRef contextParentNodeRef = lastNodeRef;
// Navigation should not check permissions
NodeRef child = authenticationUtil.runAsSystem(new RunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
return nodeService.getChildByName(contextParentNodeRef, ContentModel.ASSOC_CONTAINS, pathElement);
}
});
if(child == null)
{
break;
}
lastNodeRef = child;
}
if(i == pathElements.size())
{
QName nodeType = nodeService.getType(lastNodeRef);
if(!nodeType.equals(nodesType))
{
throw new InvalidArgumentException("The given id:'"+ parentNodeRef.getId() +"' and the relative path '"+ relativePath + "' reach a node type invalid for this endpoint."
+ " Expected nodeType is:" + nodesType.toString() + ". Actual nodeType is:" + nodeType);
}
return lastNodeRef;
}
else
{
if(!readOnlyRelativePath)
{
pathElements = pathElements.subList(i, pathElements.size());
}
else
{
throw new NotFoundException("The entity with relativePath: " + relativePath + " was not found.");
}
}
/*
* Starting from the latest existing element create the rest of the elements
*/
if(nodesType.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER))
{
for (String pathElement : pathElements)
{
lastNodeRef = fileFolderService.create(lastNodeRef, pathElement, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
}
}
else if(nodesType.equals(RecordsManagementModel.TYPE_RECORD_CATEGORY))
{
for (String pathElement : pathElements)
{
lastNodeRef = filePlanService.createRecordCategory(lastNodeRef, pathElement);
}
}
else
{
// Throw internal error as this method should not be called for other types
throw new InternalServerErrorException("Creating relative path of type '" + nodesType + "' not suported for this endpoint");
}
return lastNodeRef;
}
/**
* Helper method that parses a string representing a file path and returns a list of element names
* @param path the file path represented as a string
* @return a list of file path element names
*/
private List<String> getPathElements(String path)
{
final List<String> pathElements = new ArrayList<>();
if (path != null && path.trim().length() > 0)
{
// There is no need to check for leading and trailing "/"
final StringTokenizer tokenizer = new StringTokenizer(path, "/");
while (tokenizer.hasMoreTokens())
{
pathElements.add(tokenizer.nextToken().trim());
}
}
return pathElements;
}
/**
* Helper method that converts a map of String properties into a map of QName properties
* @param props
* @return a map of properties
*/
public Map<QName, Serializable> mapToNodeProperties(Map<String, Object> properties)
{
Map<QName, Serializable> response = null;
if(properties != null)
{
response = nodes.mapToNodeProperties(properties);
}
return response;
}
/**
* Create an RM node
*
* @param parentNodeRef the parent of the node
* @param name the name of the new node
* @param type the type of the node
* @param properties properties to set on the new node
* @param aspects aspects to set on the new node
* @return the new node
*/
public NodeRef createRMNode(NodeRef parentNodeRef, String name, String type, Map<String, Object> properties, List<String> aspects)
{
mandatory("parentNodeRef", parentNodeRef);
checkNotBlank(RMNode.PARAM_NAME, name);
checkNotBlank(RMNode.PARAM_NODE_TYPE, type);
// Create the node
NodeRef newNodeRef = null;
try
{
QName typeQName = nodes.createQName(type);
newNodeRef = fileFolderService.create(parentNodeRef, name, typeQName).getNodeRef();
// Set the provided properties if any
Map<QName, Serializable> qnameProperties = mapToNodeProperties(properties);
if (qnameProperties != null)
{
nodeService.addProperties(newNodeRef, qnameProperties);
}
// If electronic record create empty content
if (!typeQName.equals(RecordsManagementModel.TYPE_NON_ELECTRONIC_DOCUMENT)
&& dictionaryService.isSubClass(typeQName, ContentModel.TYPE_CONTENT))
{
writeContent(newNodeRef, name, new ByteArrayInputStream("".getBytes()), false);
}
// Add the provided aspects if any
if (aspects != null)
{
nodes.addCustomAspects(newNodeRef, aspects, ApiNodesModelFactory.EXCLUDED_ASPECTS);
}
}
catch (InvalidTypeException ex)
{
throw new InvalidArgumentException("The given type:'" + type + "' is invalid '");
}
return newNodeRef;
}
/**
* Upload a record
*
* @param parentNodeRef the parent of the record
* @param name the name of the record
* @param type the type of the record (if null the record's type will be cm:content)
* @param properties properties to set (can be null)
* @param stream the stream to write
* @return the new record
*/
public NodeRef uploadRecord(NodeRef parentNodeRef, String name, String type, Map<String, Object> properties, InputStream stream)
{
checkNotBlank(RMNode.PARAM_NAME, name);
mandatory("stream", stream);
// Create the node
QName typeQName = StringUtils.isBlank(type) ? ContentModel.TYPE_CONTENT : nodes.createQName(type);
if(!dictionaryService.isSubClass(typeQName, ContentModel.TYPE_CONTENT))
{
throw new InvalidArgumentException("Can only upload type of cm:content: " + typeQName);
}
NodeRef newNodeRef = fileFolderService.create(parentNodeRef, name, typeQName).getNodeRef();
// Write content
writeContent(newNodeRef, name, stream, true);
// Set the provided properties if any
Map<QName, Serializable> qnameProperties = mapToNodeProperties(properties);
if(qnameProperties != null)
{
nodeService.addProperties(newNodeRef, qnameProperties);
}
return newNodeRef;
}
/**
* Returns a List of filter properties specified by request parameters.
* @param parameters The {@link Parameters} object to get the parameters passed into the request
* including:
* - filter, sort & paging params (where, orderBy, skipCount, maxItems)
* @return The list of {@link FilterProp}. Can be null.
*/
public List<FilterProp> getListChildrenFilterProps(Parameters parameters, Set<String> listFolderChildrenEqualsQueryProperties)
{
List<FilterProp> filterProps = null;
Query q = parameters.getQuery();
if (q != null)
{
MapBasedQueryWalker propertyWalker = new MapBasedQueryWalker(listFolderChildrenEqualsQueryProperties, null);
QueryHelper.walk(q, propertyWalker);
Boolean isPrimary = propertyWalker.getProperty(RMNode.PARAM_ISPRIMARY, WhereClauseParser.EQUALS, Boolean.class);
if (isPrimary != null)
{
filterProps = new ArrayList<>(1);
filterProps.add(new FilterPropBoolean(GetChildrenCannedQuery.FILTER_QNAME_NODE_IS_PRIMARY, isPrimary));
}
Boolean isClosed = propertyWalker.getProperty(RMNode.PARAM_IS_CLOSED, WhereClauseParser.EQUALS, Boolean.class);
if (isClosed != null)
{
filterProps = new ArrayList<>(1);
filterProps.add(new FilterPropBoolean(RecordsManagementModel.PROP_IS_CLOSED, isClosed));
}
//TODO see how we can filter for categories that have retention schedule
// Boolean hasRetentionSchedule = propertyWalker.getProperty(RMNode.PARAM_HAS_RETENTION_SCHEDULE, WhereClauseParser.EQUALS, Boolean.class);
// if (hasRetentionSchedule != null)
// {
// filterProps = new ArrayList<>(1);
// }
}
return filterProps;
}
/**
* Utility method that updates a node's name and properties
* @param nodeRef the node to update
* @param updateInfo information to update the record with
* @param parameters request parameters
*/
public void updateNode(NodeRef nodeRef, RMNode updateInfo, Parameters parameters)
{
Map<QName, Serializable> props = new HashMap<>(0);
if (updateInfo.getProperties() != null)
{
props = mapToNodeProperties(updateInfo.getProperties());
}
String name = updateInfo.getName();
if ((name != null) && (!name.isEmpty()))
{
// update node name if needed
props.put(ContentModel.PROP_NAME, name);
}
try
{
// update node properties - note: null will unset the specified property
nodeService.addProperties(nodeRef, props);
}
catch (DuplicateChildNodeNameException dcne)
{
throw new ConstraintViolatedException(dcne.getMessage());
}
// update aspects
List<String> aspectNames = updateInfo.getAspectNames();
nodes.updateCustomAspects(nodeRef, aspectNames, ApiNodesModelFactory.EXCLUDED_ASPECTS);
}
/**
* Validates a record
*
* @param recordId the id of the record to validate
* @return
*/
public NodeRef validateRecord(String recordId) throws InvalidArgumentException
{
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, recordId);
if(!recordService.isRecord(nodeRef))
{
throw new IllegalArgumentException("The given id:'"+ recordId +"' is not valid for this endpoint. This endpoint only supports records.");
}
return nodeRef;
}
public BinaryResource getContent(NodeRef nodeRef, Parameters parameters, boolean recordActivity)
{
return nodes.getContent(nodeRef, parameters, recordActivity);
}
/**
* Utility method that updates a transfer container's name and properties
*
* @param nodeRef the node to update
* @param transferContainerInfo information to update the transfer container with
* @param parameters request parameters
*/
public void updateTransferContainer(NodeRef nodeRef, TransferContainer transferContainerInfo, Parameters parameters)
{
Map<QName, Serializable> props = new HashMap<>(0);
if (transferContainerInfo.getProperties() != null)
{
props = mapToNodeProperties(transferContainerInfo.getProperties());
}
String name = transferContainerInfo.getName();
if ((name != null) && (!name.isEmpty()))
{
// update node name if needed
props.put(ContentModel.PROP_NAME, name);
}
try
{
// update node properties - note: null will unset the specified property
nodeService.addProperties(nodeRef, props);
}
catch (DuplicateChildNodeNameException dcne)
{
throw new ConstraintViolatedException(dcne.getMessage());
}
}
/**
* Helper method that generates allowable operation for the provided node
* @param nodeRef the node to get the allowable operations for
* @param type the type of the provided nodeRef
* @return a sublist of [{@link Nodes.OP_DELETE}, {@link Nodes.OP_CREATE}, {@link Nodes.OP_UPDATE}] representing the allowable operations for the provided node
*/
protected List<String> getAllowableOperations(NodeRef nodeRef, QName typeQName)
{
List<String> allowableOperations = new ArrayList<>();
boolean isFilePlan = typeQName.equals(RecordsManagementModel.TYPE_FILE_PLAN);
boolean isTransferContainer = typeQName.equals(RecordsManagementModel.TYPE_TRANSFER_CONTAINER);
boolean isUnfiledContainer = typeQName.equals(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER);
boolean isHoldsContainer = typeQName.equals(RecordsManagementModel.TYPE_HOLD_CONTAINER);
boolean isSpecialContainer = isFilePlan || isTransferContainer || isUnfiledContainer || isHoldsContainer;
// DELETE
if(!isSpecialContainer &&
capabilityService.getCapability("Delete").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{
allowableOperations.add(Nodes.OP_DELETE);
}
// CREATE
if(TYPES_CAN_CREATE.contains(typeQName) &&
capabilityService.getCapability("FillingPermissionOnly").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{
allowableOperations.add(Nodes.OP_CREATE);
}
// UPDATE
if (capabilityService.getCapability("Update").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{
allowableOperations.add(Nodes.OP_UPDATE);
}
return allowableOperations;
}
protected PathInfo lookupPathInfo(NodeRef nodeRefIn)
{
List<ElementInfo> pathElements = new ArrayList<>();
Boolean isComplete = Boolean.TRUE;
final Path nodePath = nodeService.getPath(nodeRefIn);;
final int pathIndex = 2;
for (int i = nodePath.size() - pathIndex; i >= 0; i--)
{
Element element = nodePath.get(i);
if (element instanceof Path.ChildAssocElement)
{
ChildAssociationRef elementRef = ((Path.ChildAssocElement) element).getRef();
if (elementRef.getParentRef() != null)
{
NodeRef childNodeRef = elementRef.getChildRef();
if (permissionService.hasPermission(childNodeRef, PermissionService.READ) == AccessStatus.ALLOWED)
{
Serializable nameProp = nodeService.getProperty(childNodeRef, ContentModel.PROP_NAME);
pathElements.add(0, new ElementInfo(childNodeRef.getId(), nameProp.toString()));
}
else
{
// Just return the pathInfo up to the location where the user has access
isComplete = Boolean.FALSE;
break;
}
}
}
}
String pathStr = null;
if (pathElements.size() > 0)
{
StringBuilder sb = new StringBuilder(120);
for (PathInfo.ElementInfo e : pathElements)
{
sb.append("/").append(e.getName());
}
pathStr = sb.toString();
}
else
{
// There is no path element, so set it to null in order to be
// ignored by Jackson during serialisation
isComplete = null;
}
return new PathInfo(pathStr, isComplete, pathElements);
}
/**
* Helper method to obtain file plan type or null if the rm site does not exist.
*
* @return file plan type or null
*/
public QName getFilePlanType()
{
NodeRef filePlanNodeRef = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if(filePlanNodeRef != null)
{
return nodeService.getType(filePlanNodeRef);
}
return null;
}
/**
* Posts activities for given fileInfo
*
* @param fileInfo
* @param parentNodeRef
* @param activityType
*/
public void postActivity(FileInfo fileInfo, NodeRef parentNodeRef, String activityType)
{
ActivityInfo activityInfo = null;
RMSite rmSite = sites.getRMSite(RM_SITE_ID);
if (rmSite != null && !rmSite.getId().equals(""))
{
if (fileInfo != null)
{
boolean isContent = dictionaryService.isSubClass(fileInfo.getType(), ContentModel.TYPE_CONTENT);
if (isContent)
{
activityInfo = new ActivityInfo(null, parentNodeRef, RM_SITE_ID, fileInfo);
}
}
}
else
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("Non-site activity, so ignored " + fileInfo.getNodeRef());
}
}
if (activityInfo == null)
return; // Nothing to do.
if (activityType != null)
{
activityPoster.postFileFolderActivity(activityType, null, TenantUtil.getCurrentDomain(), activityInfo.getSiteId(),
activityInfo.getParentNodeRef(), activityInfo.getNodeRef(), activityInfo.getFileName(), Activities.APP_TOOL,
Activities.RESTAPI_CLIENT, activityInfo.getFileInfo());
}
}
}

View File

@@ -1,497 +0,0 @@
/*
* #%L
* Alfresco Records Management Module
* %%
* Copyright (C) 2005 - 2017 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.rm.rest.api.impl;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.RecordsManagementServiceRegistry;
import org.alfresco.module.org_alfresco_module_rm.capability.CapabilityService;
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.fileplan.FilePlanService;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.impl.NodesImpl;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.api.model.UserInfo;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.RMNodes;
import org.alfresco.rm.rest.api.model.FileplanComponentNode;
import org.alfresco.rm.rest.api.model.RecordCategoryNode;
import org.alfresco.rm.rest.api.model.RecordFolderNode;
import org.alfresco.rm.rest.api.model.RecordNode;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.webscripts.servlet.FormData;
import net.sf.acegisecurity.vote.AccessDecisionVoter;
/**
* Centralizes access to the repository.
*
* @author Ana Bozianu
* @since 2.6
*/
public class RMNodesImpl extends NodesImpl implements RMNodes
{
private enum RMNodeType
{
// Note: ordered
CATEGORY, RECORD_FOLDER, FILE
}
private FilePlanService filePlanService;
private NodeService nodeService;
private RecordsManagementServiceRegistry serviceRegistry;
private DictionaryService dictionaryService;
private DispositionService dispositionService;
private CapabilityService capabilityService;
private FileFolderService fileFolderService;
public void init()
{
super.init();
this.nodeService = serviceRegistry.getNodeService();
this.dictionaryService = serviceRegistry.getDictionaryService();
this.dispositionService = serviceRegistry.getDispositionService();
}
public void setRecordsManagementServiceRegistry(RecordsManagementServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
public void setFilePlanService(FilePlanService filePlanService)
{
this.filePlanService = filePlanService;
}
public void setCapabilityService(CapabilityService capabilityService)
{
this.capabilityService = capabilityService;
}
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
@Override
public Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, List<String> includeParam, Map<String, UserInfo> mapUserInfo)
{
Node originalNode = super.getFolderOrDocument(nodeRef, parentNodeRef, nodeTypeQName, includeParam, mapUserInfo);
if(nodeTypeQName == null)
{
nodeTypeQName = nodeService.getType(nodeRef);
}
RMNodeType type = getType(nodeTypeQName, nodeRef);
FileplanComponentNode node = null;
if (mapUserInfo == null)
{
mapUserInfo = new HashMap<>(2);
}
if (type == null)
{
if (filePlanService.isFilePlanComponent(nodeRef))
{
node = new FileplanComponentNode(originalNode);
}
else
{
throw new InvalidParameterException("The provided node is not a fileplan component");
}
}
else
{
switch(type)
{
case CATEGORY:
RecordCategoryNode categoryNode = new RecordCategoryNode(originalNode);
if (includeParam.contains(PARAM_INCLUDE_HAS_RETENTION_SCHEDULE))
{
DispositionSchedule ds = dispositionService.getDispositionSchedule(nodeRef);
categoryNode.setHasRetentionSchedule(ds!=null?true:false);
}
node = categoryNode;
break;
case RECORD_FOLDER:
RecordFolderNode rfNode = new RecordFolderNode(originalNode);
if (includeParam.contains(PARAM_INCLUDE_IS_CLOSED))
{
rfNode.setIsClosed((Boolean) nodeService.getProperty(nodeRef, RecordsManagementModel.PROP_IS_CLOSED));
}
node = rfNode;
break;
case FILE:
RecordNode rNode = new RecordNode(originalNode);
if (includeParam.contains(PARAM_INCLUDE_IS_COMPLETED))
{
rNode.setIsCompleted(nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_DECLARED_RECORD));
}
node = rNode;
break;
}
}
if (includeParam.contains(PARAM_INCLUDE_ALLOWABLEOPERATIONS))
{
// If the user does not have any of the mapped permissions then "allowableOperations" is not returned (rather than an empty array)
List<String> allowableOperations = getAllowableOperations(nodeRef, type);
node.setAllowableOperations((allowableOperations.size() > 0 )? allowableOperations : null);
}
return node;
}
/**
* Helper method that generates allowable operation for the provided node
* @param nodeRef the node to get the allowable operations for
* @param type the type of the provided nodeRef
* @return a sublist of [{@link Nodes.OP_DELETE}, {@link Nodes.OP_CREATE}, {@link Nodes.OP_UPDATE}] representing the allowable operations for the provided node
*/
private List<String> getAllowableOperations(NodeRef nodeRef, RMNodeType type)
{
List<String> allowableOperations = new ArrayList<>();
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
boolean isFilePlan = nodeRef.equals(filePlan);
boolean isTransferContainer = nodeRef.equals(filePlanService.getTransferContainer(filePlan));
boolean isUnfiledContainer = nodeRef.equals(filePlanService.getUnfiledContainer(filePlan));
boolean isHoldsContainer = nodeRef.equals(filePlanService.getHoldContainer(filePlan)) ;
boolean isSpecialContainer = isFilePlan || isTransferContainer || isUnfiledContainer || isHoldsContainer;
// DELETE
if(!isSpecialContainer &&
capabilityService.getCapability("Delete").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{
allowableOperations.add(OP_DELETE);
}
// CREATE
if(type != RMNodeType.FILE &&
!isTransferContainer &&
capabilityService.getCapability("FillingPermissionOnly").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{
allowableOperations.add(OP_CREATE);
}
// UPDATE
if (capabilityService.getCapability("Update").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{
allowableOperations.add(OP_UPDATE);
}
return allowableOperations;
}
@Override
public NodeRef validateNode(String nodeId)
{
ParameterCheck.mandatoryString("nodeId", nodeId);
if (nodeId.equals(PATH_FILE_PLAN))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
return filePlan;
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else if (nodeId.equals(PATH_TRANSFERS))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
return filePlanService.getTransferContainer(filePlan);
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else if (nodeId.equals(PATH_UNFILED))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
return filePlanService.getUnfiledContainer(filePlan);
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
else if (nodeId.equals(PATH_HOLDS))
{
NodeRef filePlan = filePlanService.getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
if (filePlan != null)
{
return filePlanService.getHoldContainer(filePlan);
}
else
{
throw new EntityNotFoundException(nodeId);
}
}
return super.validateNode(nodeId);
}
private RMNodeType getType(QName typeQName, NodeRef nodeRef)
{
// quick check for common types
if (typeQName.equals(RecordsManagementModel.TYPE_RECORD_FOLDER))
{
return RMNodeType.RECORD_FOLDER;
}
if (typeQName.equals(RecordsManagementModel.TYPE_RECORD_CATEGORY))
{
return RMNodeType.CATEGORY;
}
if (typeQName.equals(ContentModel.TYPE_CONTENT))
{
return RMNodeType.FILE;
}
// check subclasses
if (dictionaryService.isSubClass(typeQName, ContentModel.TYPE_CONTENT))
{
return RMNodeType.FILE;
}
if (dictionaryService.isSubClass(typeQName, RecordsManagementModel.TYPE_RECORD_FOLDER))
{
return RMNodeType.RECORD_FOLDER;
}
return null;
}
@Override
protected Pair<Set<QName>, Set<QName>> buildSearchTypesAndIgnoreAspects(QName nodeTypeQName, boolean includeSubTypes, Set<QName> ignoreQNameTypes, Boolean includeFiles, Boolean includeFolders)
{
Pair<Set<QName>, Set<QName>> searchTypesAndIgnoreAspects = super.buildSearchTypesAndIgnoreAspects(nodeTypeQName, includeSubTypes, ignoreQNameTypes, includeFiles, includeFolders);
Set<QName> searchTypeQNames = searchTypesAndIgnoreAspects.getFirst();
Set<QName> ignoreAspectQNames = searchTypesAndIgnoreAspects.getSecond();
searchTypeQNames.remove(RecordsManagementModel.TYPE_HOLD_CONTAINER);
searchTypeQNames.remove(RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER);
searchTypeQNames.remove(RecordsManagementModel.TYPE_TRANSFER_CONTAINER);
searchTypeQNames.remove(RecordsManagementModel.TYPE_DISPOSITION_SCHEDULE);
searchTypeQNames.remove(RecordsManagementModel.TYPE_DISPOSITION_ACTION);
searchTypeQNames.remove(RecordsManagementModel.TYPE_DISPOSITION_ACTION_DEFINITION);
return new Pair<>(searchTypeQNames, ignoreAspectQNames);
}
@Override
public Node createNode(String parentFolderNodeId, Node nodeInfo, Parameters parameters)
{
// create RM path if needed and call the super method with the last element of the created path
String relativePath = nodeInfo.getRelativePath();
// Get the type of the node to be created
String nodeType = nodeInfo.getNodeType();
if ((nodeType == null) || nodeType.isEmpty())
{
throw new InvalidArgumentException("Node type is expected: "+parentFolderNodeId+","+nodeInfo.getName());
}
QName nodeTypeQName = createQName(nodeType);
// Get or create the path
NodeRef parentNodeRef = getOrCreatePath(parentFolderNodeId, relativePath, nodeTypeQName);
// Set relative path to null as we pass the last element from the path
nodeInfo.setRelativePath(null);
return super.createNode(parentNodeRef.getId(), nodeInfo, parameters);
}
@Override
public Node upload(String parentFolderNodeId, FormData formData, Parameters parameters)
{
if (formData == null || !formData.getIsMultiPart())
{
throw new InvalidArgumentException("The request content-type is not multipart: "+parentFolderNodeId);
}
for (FormData.FormField field : formData.getFields())
{
if(field.getName().equalsIgnoreCase("relativepath"))
{
// Create the path if it does not exist
getOrCreatePath(parentFolderNodeId, getStringOrNull(field.getValue()), ContentModel.TYPE_CONTENT);
break;
}
}
return super.upload(parentFolderNodeId, formData, parameters);
}
private String getStringOrNull(String value)
{
if (StringUtils.isNotEmpty(value))
{
return value.equalsIgnoreCase("null") ? null : value;
}
return null;
}
@Override
public NodeRef getOrCreatePath(String parentFolderNodeId, String relativePath, QName nodeTypeQName)
{
NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
if (relativePath == null)
{
return parentNodeRef;
}
List<String> pathElements = getPathElements(relativePath);
if (pathElements.isEmpty())
{
return parentNodeRef;
}
/*
* Get the latest existing path element
*/
int i = 0;
for (; i < pathElements.size(); i++)
{
final String pathElement = pathElements.get(i);
final NodeRef contextParentNodeRef = parentNodeRef;
// Navigation should not check permissions
NodeRef child = AuthenticationUtil.runAsSystem(new RunAsWork<NodeRef>()
{
@Override
public NodeRef doWork() throws Exception
{
return nodeService.getChildByName(contextParentNodeRef, ContentModel.ASSOC_CONTAINS, pathElement);
}
});
if(child == null)
{
break;
}
parentNodeRef = child;
}
if(i == pathElements.size())
{
return parentNodeRef;
}
else
{
pathElements = pathElements.subList(i, pathElements.size());
}
/*
* Starting from the latest existing element create the rest of the elements
*/
QName parentNodeType = nodeService.getType(parentNodeRef);
if(dictionaryService.isSubClass(parentNodeType, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER) ||
dictionaryService.isSubClass(parentNodeType, RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER))
{
for (String pathElement : pathElements)
{
// Create unfiled record folder
parentNodeRef = fileFolderService.create(parentNodeRef, pathElement, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
}
}
else
{
/* Outside the unfiled record container the path elements are record categories
* except the last element which is a record folder if the created node is of type content
*/
Iterator<String> iterator = pathElements.iterator();
while(iterator.hasNext())
{
String pathElement = iterator.next();
if(!iterator.hasNext() && dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT))
{
// last element, create record folder if the node to be created is content
parentNodeRef = fileFolderService.create(parentNodeRef, pathElement, RecordsManagementModel.TYPE_RECORD_FOLDER).getNodeRef();
}
else
{
// create record category
parentNodeRef = filePlanService.createRecordCategory(parentNodeRef, pathElement);
}
}
}
return parentNodeRef;
}
/**
* Helper method that parses a string representing a file path and returns a list of element names
* @param path the file path represented as a string
* @return a list of file path element names
*/
private List<String> getPathElements(String path)
{
final List<String> pathElements = new ArrayList<>();
if (path != null && path.trim().length() > 0)
{
// There is no need to check for leading and trailing "/"
final StringTokenizer tokenizer = new StringTokenizer(path, "/");
while (tokenizer.hasMoreTokens())
{
pathElements.add(tokenizer.nextToken().trim());
}
}
return pathElements;
}
}

View File

@@ -27,31 +27,19 @@
package org.alfresco.rm.rest.api.impl;
import org.alfresco.model.ContentModel;
import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model;
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.site.SiteServiceException;
import org.alfresco.rest.api.impl.SiteImportPackageHandler;
import org.alfresco.rest.api.impl.SitesImpl;
import org.alfresco.rest.api.model.Site;
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
import org.alfresco.rest.api.model.SiteUpdate;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.parameters.Parameters;
import org.alfresco.rm.rest.api.RMSites;
import org.alfresco.rm.rest.api.model.RMSite;
import org.alfresco.rm.rest.api.model.RMSiteCompliance;
import org.alfresco.rm.rest.api.model.SiteUpdate;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.cmr.site.SiteVisibility;
import org.alfresco.service.cmr.view.ImportPackageHandler;
import org.alfresco.service.cmr.view.ImporterBinding;
import org.alfresco.service.cmr.view.ImporterContentCache;
import org.alfresco.service.cmr.view.ImporterProgress;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName;
/**
@@ -79,134 +67,19 @@ public class RMSitesImpl extends SitesImpl implements RMSites
return new RMSite(site, compliance);
}
/**
* TODO remove when upgrading to 5.2.N. We'll need to only extend the extended method createSite(Site) and use the siteService method that gets site type as parameter
*/
@Override
public Site createSite(Site site, Parameters parameters)
protected SiteInfo createSite(Site site)
{
site = validateSite(site);
SiteInfo siteInfo = null;
try
{
siteInfo = siteService.createSite(RM_SITE_PRESET, RM_SITE_ID, site.getTitle(), site.getDescription(),
SiteVisibility.PUBLIC, getRMSiteType((RMSite) site));
}
catch (SiteServiceException sse)
{
if (sse.getMsgId().equals("site_service.unable_to_create"))
{
throw new ConstraintViolatedException(sse.getMessage());
}
else
{
throw sse;
}
}
String siteId = siteInfo.getShortName();
NodeRef siteNodeRef = siteInfo.getNodeRef();
// import default/fixed preset Share surf config
importSite(siteId, siteNodeRef);
// pre-create doclib
siteService.createContainer(siteId, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null);
// default false (if not provided)
boolean skipAddToFavorites = Boolean.valueOf(parameters.getParameter(PARAM_SKIP_ADDTOFAVORITES));
if (skipAddToFavorites == false)
{
String personId = AuthenticationUtil.getFullyAuthenticatedUser();
favouritesService.addFavourite(personId, siteNodeRef); // ignore result
}
return getSite(siteInfo, true);
return siteService.createSite(RM_SITE_PRESET, RM_SITE_ID, site.getTitle(), site.getDescription(), SiteVisibility.PUBLIC, getRMSiteType((RMSite) site));
}
/**
* Copied from SitesImpl since we didn't had access to it.
*
* TODO to remove when upgrading to 5.2.N
*
* @param siteInfo
* @param includeRole
* @return
*/
private Site getSite(SiteInfo siteInfo, boolean includeRole)
{
// set the site id to the short name (to deal with case sensitivity issues with using the siteId from the url)
String siteId = siteInfo.getShortName();
String role = null;
if (includeRole)
{
role = getSiteRole(siteId);
}
return new Site(siteInfo, role);
}
/**
* Copied from SitesImpl since we didn't had access to it.
*
* TODO to be removed when upgrading to 5.2.N
*
* @param siteId
* @param siteNodeRef
*/
private void importSite(final String siteId, final NodeRef siteNodeRef)
{
ImportPackageHandler acpHandler = new SiteImportPackageHandler(siteSurfConfig, siteId);
Location location = new Location(siteNodeRef);
ImporterBinding binding = new ImporterBinding()
{
@Override
public String getValue(String key)
{
if (key.equals("siteId"))
{
return siteId;
}
return null;
}
@Override
public UUID_BINDING getUUIDBinding()
{
return UUID_BINDING.CREATE_NEW;
}
@Override
public QName[] getExcludedClasses()
{
return null;
}
@Override
public boolean allowReferenceWithinTransaction()
{
return false;
}
@Override
public ImporterContentCache getImportConentCache()
{
return null;
}
};
importerService.importView(acpHandler, location, binding, (ImporterProgress)null);
}
/**
* This method is copied from SitesImpl since we could not access it since it is private.
*
* TODO change this to protected and override validate method from core when upgrading to 5.2.N
*
* Even if the method it will be protected in core, we still need to override since we don't need to check if the visibility is set since for RM site it is always PUBLIC.
* We also don't need to generate the id from title, or to check the id, since the id is always rm.
* @param site
* @return
*/
@Override
protected Site validateSite(Site site)
{
// site title - mandatory
@@ -269,46 +142,6 @@ public class RMSitesImpl extends SitesImpl implements RMSites
return compliance;
}
/**
* TODO copied from core 5.2.N since we don't have it in 5.2.a-EA version. To be removed when upgrading.
* @param siteId
* @param update
* @param parameters
* @return
*/
public Site updateSite(String siteId, SiteUpdate update, Parameters parameters)
{
// Get the site by ID (aka short name)
SiteInfo siteInfo = validateSite(siteId);
if (siteInfo == null)
{
// site does not exist
throw new EntityNotFoundException(siteId);
}
// Bind any provided values to the site info, allowing for "partial" updates.
if (update.getTitle() != null)
{
siteInfo.setTitle(update.getTitle());
}
if (update.getDescription() != null)
{
siteInfo.setDescription(update.getDescription());
}
if (update.getVisibility() != null)
{
siteInfo.setVisibility(update.getVisibility());
}
// Validate the new details
validateSite(new Site(siteInfo, null));
// Perform the actual update.
siteService.updateSite(siteInfo);
return getSite(siteId);
}
/**
* Gets RM site type based on compliance.
*

Some files were not shown because too many files have changed in this diff Show More