MIFOSX-97: repackage document management code.
This commit is contained in:
-281
@@ -1,281 +0,0 @@
|
|||||||
package org.mifosng.platform.api;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.HeaderParam;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
|
|
||||||
import org.mifosng.platform.api.commands.DocumentCommand;
|
|
||||||
import org.mifosng.platform.api.data.DocumentData;
|
|
||||||
import org.mifosng.platform.documentmanagement.service.DocumentReadPlatformService;
|
|
||||||
import org.mifosng.platform.documentmanagement.service.DocumentWritePlatformService;
|
|
||||||
import org.mifosplatform.infrastructure.core.api.ApiConstants;
|
|
||||||
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
|
||||||
import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
|
||||||
import org.mifosplatform.infrastructure.core.service.FileUtils;
|
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.sun.jersey.core.header.FormDataContentDisposition;
|
|
||||||
import com.sun.jersey.multipart.FormDataBodyPart;
|
|
||||||
import com.sun.jersey.multipart.FormDataParam;
|
|
||||||
|
|
||||||
@Path("{entityType}/{entityId}/documents")
|
|
||||||
@Component
|
|
||||||
@Scope("singleton")
|
|
||||||
public class DocumentManagementApiResource {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DocumentReadPlatformService documentReadPlatformService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DocumentWritePlatformService documentWritePlatformService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PortfolioApiJsonSerializerService apiJsonSerializerService;
|
|
||||||
|
|
||||||
private static final Set<String> typicalResponseParameters = new HashSet<String>(
|
|
||||||
Arrays.asList("id", "parentEntityType", "parentEntityId", "name",
|
|
||||||
"fileName", "type", "size", "description"));
|
|
||||||
|
|
||||||
private final String SystemEntityType = "DOCUMENT";
|
|
||||||
@Autowired
|
|
||||||
private PlatformSecurityContext context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uriInfo
|
|
||||||
* @param entityType
|
|
||||||
* @param entityId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String retreiveAllDocuments(@Context final UriInfo uriInfo,
|
|
||||||
@PathParam("entityType") String entityType,
|
|
||||||
@PathParam("entityId") Long entityId) {
|
|
||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(SystemEntityType);
|
|
||||||
|
|
||||||
Set<String> responseParameters = ApiParameterHelper
|
|
||||||
.extractFieldsForResponseIfProvided(uriInfo
|
|
||||||
.getQueryParameters());
|
|
||||||
if (responseParameters.isEmpty()) {
|
|
||||||
responseParameters.addAll(typicalResponseParameters);
|
|
||||||
}
|
|
||||||
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
|
||||||
.getQueryParameters());
|
|
||||||
|
|
||||||
Collection<DocumentData> documentDatas = this.documentReadPlatformService
|
|
||||||
.retrieveAllDocuments(entityType, entityId);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serializeDocumentDataToJson(
|
|
||||||
prettyPrint, responseParameters, documentDatas);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param entityType
|
|
||||||
* @param entityId
|
|
||||||
* @param fileSize
|
|
||||||
* @param inputStream
|
|
||||||
* @param fileDetails
|
|
||||||
* @param bodyPart
|
|
||||||
* @param name
|
|
||||||
* @param description
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@POST
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public Response createDocument(@PathParam("entityType") String entityType,
|
|
||||||
@PathParam("entityId") Long entityId,
|
|
||||||
@HeaderParam("Content-Length") Long fileSize,
|
|
||||||
@FormDataParam("file") InputStream inputStream,
|
|
||||||
@FormDataParam("file") FormDataContentDisposition fileDetails,
|
|
||||||
@FormDataParam("file") FormDataBodyPart bodyPart,
|
|
||||||
@FormDataParam("name") String name,
|
|
||||||
@FormDataParam("description") String description) {
|
|
||||||
|
|
||||||
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: also need to have a backup and stop reading from stream after
|
|
||||||
* max size is reached to protect against malicious clients
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: need to extract the actual file type and determine if they are
|
|
||||||
* permissable
|
|
||||||
**/
|
|
||||||
DocumentCommand documentCommand = new DocumentCommand(null, null,
|
|
||||||
entityType, entityId, name, fileDetails.getFileName(),
|
|
||||||
fileSize, bodyPart.getMediaType().toString(), description, null);
|
|
||||||
|
|
||||||
Long documentId = this.documentWritePlatformService.createDocument(
|
|
||||||
documentCommand, inputStream);
|
|
||||||
|
|
||||||
return Response.ok().entity(new EntityIdentifier(documentId)).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param entityType
|
|
||||||
* @param entityId
|
|
||||||
* @param documentId
|
|
||||||
* @param fileSize
|
|
||||||
* @param inputStream
|
|
||||||
* @param fileDetails
|
|
||||||
* @param bodyPart
|
|
||||||
* @param name
|
|
||||||
* @param description
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@PUT
|
|
||||||
@Path("{documentId}")
|
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public Response updateDocument(@PathParam("entityType") String entityType,
|
|
||||||
@PathParam("entityId") Long entityId,
|
|
||||||
@PathParam("documentId") Long documentId,
|
|
||||||
@HeaderParam("Content-Length") Long fileSize,
|
|
||||||
@FormDataParam("file") InputStream inputStream,
|
|
||||||
@FormDataParam("file") FormDataContentDisposition fileDetails,
|
|
||||||
@FormDataParam("file") FormDataBodyPart bodyPart,
|
|
||||||
@FormDataParam("name") String name,
|
|
||||||
@FormDataParam("description") String description) {
|
|
||||||
|
|
||||||
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
|
|
||||||
|
|
||||||
Set<String> modifiedParams = new HashSet<String>();
|
|
||||||
modifiedParams.add("name");
|
|
||||||
modifiedParams.add("description");
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Populate Document command based on whether a file has also been
|
|
||||||
* passed in as a part of the update
|
|
||||||
***/
|
|
||||||
DocumentCommand documentCommand = null;
|
|
||||||
if (inputStream != null && fileDetails.getFileName() != null) {
|
|
||||||
modifiedParams.add("fileName");
|
|
||||||
modifiedParams.add("size");
|
|
||||||
modifiedParams.add("type");
|
|
||||||
modifiedParams.add("location");
|
|
||||||
documentCommand = new DocumentCommand(modifiedParams, documentId,
|
|
||||||
entityType, entityId, name, fileDetails.getFileName(),
|
|
||||||
fileSize, bodyPart.getMediaType().toString(), description,
|
|
||||||
null);
|
|
||||||
} else {
|
|
||||||
documentCommand = new DocumentCommand(modifiedParams, documentId,
|
|
||||||
entityType, entityId, name, null, null, null, description,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
EntityIdentifier identifier = this.documentWritePlatformService
|
|
||||||
.updateDocument(documentCommand, inputStream);
|
|
||||||
|
|
||||||
return Response.ok().entity(identifier).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param entityType
|
|
||||||
* @param entityId
|
|
||||||
* @param documentId
|
|
||||||
* @param uriInfo
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@Path("{documentId}")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public String getDocument(@PathParam("entityType") String entityType,
|
|
||||||
@PathParam("entityId") Long entityId,
|
|
||||||
@PathParam("documentId") Long documentId,
|
|
||||||
@Context final UriInfo uriInfo) {
|
|
||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(SystemEntityType);
|
|
||||||
|
|
||||||
Set<String> responseParameters = ApiParameterHelper
|
|
||||||
.extractFieldsForResponseIfProvided(uriInfo
|
|
||||||
.getQueryParameters());
|
|
||||||
if (responseParameters.isEmpty()) {
|
|
||||||
responseParameters.addAll(typicalResponseParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo
|
|
||||||
.getQueryParameters());
|
|
||||||
|
|
||||||
DocumentData documentData = this.documentReadPlatformService
|
|
||||||
.retrieveDocument(entityType, entityId, documentId);
|
|
||||||
|
|
||||||
return this.apiJsonSerializerService.serializeDocumentDataToJson(
|
|
||||||
prettyPrint, responseParameters, documentData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param entityType
|
|
||||||
* @param entityId
|
|
||||||
* @param documentId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@Path("{documentId}/attachment")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public Response downloadFile(@PathParam("entityType") String entityType,
|
|
||||||
@PathParam("entityId") Long entityId,
|
|
||||||
@PathParam("documentId") Long documentId) {
|
|
||||||
|
|
||||||
context.authenticatedUser().validateHasReadPermission(SystemEntityType);
|
|
||||||
|
|
||||||
DocumentData documentData = this.documentReadPlatformService
|
|
||||||
.retrieveDocument(entityType, entityId, documentId);
|
|
||||||
File file = new File(documentData.getLocation());
|
|
||||||
ResponseBuilder response = Response.ok(file);
|
|
||||||
response.header("Content-Disposition", "attachment; filename=\""
|
|
||||||
+ documentData.getFileName() + "\"");
|
|
||||||
response.header("Content-Type", documentData.getType());
|
|
||||||
return response.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param entityType
|
|
||||||
* @param entityId
|
|
||||||
* @param documentId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@DELETE
|
|
||||||
@Path("{documentId}")
|
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
|
||||||
@Produces({ MediaType.APPLICATION_JSON })
|
|
||||||
public Response deleteDocument(@PathParam("entityType") String entityType,
|
|
||||||
@PathParam("entityId") Long entityId,
|
|
||||||
@PathParam("documentId") Long documentId) {
|
|
||||||
DocumentCommand documentCommand = new DocumentCommand(null, documentId,
|
|
||||||
entityType, entityId, null, null, null, null, null, null);
|
|
||||||
|
|
||||||
EntityIdentifier documentIdentifier = this.documentWritePlatformService
|
|
||||||
.deleteDocument(documentCommand);
|
|
||||||
|
|
||||||
return Response.ok(documentIdentifier).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-119
@@ -1,119 +0,0 @@
|
|||||||
package org.mifosng.platform.api.commands;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Immutable command for creating or updating details of a client identifier.
|
|
||||||
*/
|
|
||||||
public class DocumentCommand {
|
|
||||||
|
|
||||||
private final Long id;
|
|
||||||
private final String parentEntityType;
|
|
||||||
private final Long parentEntityId;
|
|
||||||
private final String name;
|
|
||||||
private final String description;
|
|
||||||
|
|
||||||
private String fileName;
|
|
||||||
private Long size;
|
|
||||||
private String type;
|
|
||||||
private String location;
|
|
||||||
|
|
||||||
private final Set<String> modifiedParameters;
|
|
||||||
|
|
||||||
public DocumentCommand(final Set<String> modifiedParameters, final Long id,
|
|
||||||
final String parentEntityType, final Long parentEntityId,
|
|
||||||
final String name, final String fileName, Long size, String type,
|
|
||||||
final String description, String location) {
|
|
||||||
this.modifiedParameters = modifiedParameters;
|
|
||||||
this.id = id;
|
|
||||||
this.parentEntityType = parentEntityType;
|
|
||||||
this.parentEntityId = parentEntityId;
|
|
||||||
this.name = name;
|
|
||||||
this.fileName = fileName;
|
|
||||||
this.size = size;
|
|
||||||
this.type = type;
|
|
||||||
this.description = description;
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParentEntityType() {
|
|
||||||
return parentEntityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getParentEntityId() {
|
|
||||||
return parentEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getModifiedParameters() {
|
|
||||||
return modifiedParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileName(String fileName) {
|
|
||||||
this.fileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(Long size) {
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(String location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNameChanged() {
|
|
||||||
return this.modifiedParameters.contains("name");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFileNameChanged() {
|
|
||||||
return this.modifiedParameters.contains("fileName");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSizeChanged() {
|
|
||||||
return this.modifiedParameters.contains("size");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFileTypeChanged() {
|
|
||||||
return this.modifiedParameters.contains("type");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDescriptionChanged() {
|
|
||||||
return this.modifiedParameters.contains("description");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLocationChanged() {
|
|
||||||
return this.modifiedParameters.contains("location");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package org.mifosng.platform.api.data;
|
|
||||||
|
|
||||||
|
|
||||||
public class DocumentData {
|
|
||||||
|
|
||||||
private final Long id;
|
|
||||||
private final String parentEntityType;
|
|
||||||
private final Long parentEntityId;
|
|
||||||
private final String name;
|
|
||||||
private final String fileName;
|
|
||||||
private final Long size;
|
|
||||||
private final String type;
|
|
||||||
private final String description;
|
|
||||||
private final String location;
|
|
||||||
|
|
||||||
public DocumentData(final Long id, final String parentEntityType,
|
|
||||||
final Long parentEntityId, final String name,
|
|
||||||
final String fileName, final Long size, final String type,
|
|
||||||
final String description, final String location) {
|
|
||||||
this.id = id;
|
|
||||||
this.parentEntityType = parentEntityType;
|
|
||||||
this.parentEntityId = parentEntityId;
|
|
||||||
this.name = name;
|
|
||||||
this.fileName = fileName;
|
|
||||||
this.size = size;
|
|
||||||
this.type = type;
|
|
||||||
this.description = description;
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParentEntityType() {
|
|
||||||
return parentEntityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getParentEntityId() {
|
|
||||||
return parentEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-150
@@ -1,150 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.domain;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.mifosng.platform.api.commands.DocumentCommand;
|
|
||||||
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
|
||||||
import org.mifosplatform.infrastructure.user.domain.AppUser;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "m_document")
|
|
||||||
public class Document extends AbstractAuditableCustom<AppUser, Long> {
|
|
||||||
|
|
||||||
@Column(name = "parent_entity_type", length = 50)
|
|
||||||
private String parentEntityType;
|
|
||||||
|
|
||||||
@Column(name = "parent_entity_id", length = 1000)
|
|
||||||
private Long parentEntityId;
|
|
||||||
|
|
||||||
@Column(name = "name", length = 250)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@Column(name = "file_name", length = 250)
|
|
||||||
private String fileName;
|
|
||||||
|
|
||||||
@Column(name = "size")
|
|
||||||
private Long size;
|
|
||||||
|
|
||||||
@Column(name = "type", length = 50)
|
|
||||||
private String type;
|
|
||||||
|
|
||||||
@Column(name = "description", length = 1000)
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
@Column(name = "location", length = 500)
|
|
||||||
private String location;
|
|
||||||
|
|
||||||
public Document() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Document createNew(String parentEntityType,
|
|
||||||
Long parentEntityId, String name, String fileName, Long size,
|
|
||||||
String type, String description, String location) {
|
|
||||||
return new Document(parentEntityType, parentEntityId, name, fileName,
|
|
||||||
size, type, description, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Document(String parentEntityType, Long parentEntityId, String name,
|
|
||||||
String fileName, Long size, String type, String description,
|
|
||||||
String location) {
|
|
||||||
this.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType,
|
|
||||||
null);
|
|
||||||
this.parentEntityId = parentEntityId;
|
|
||||||
this.name = StringUtils.defaultIfEmpty(name, null);
|
|
||||||
this.fileName = StringUtils.defaultIfEmpty(fileName, null);
|
|
||||||
this.size = size;
|
|
||||||
this.type = StringUtils.defaultIfEmpty(type, null);
|
|
||||||
this.description = StringUtils.defaultIfEmpty(description, null);
|
|
||||||
this.location = StringUtils.defaultIfEmpty(location, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(final DocumentCommand command) {
|
|
||||||
if (command.isDescriptionChanged()) {
|
|
||||||
this.description = command.getDescription();
|
|
||||||
}
|
|
||||||
if (command.isFileNameChanged()) {
|
|
||||||
this.fileName = command.getFileName();
|
|
||||||
}
|
|
||||||
if (command.isFileTypeChanged()) {
|
|
||||||
this.type = command.getType();
|
|
||||||
}
|
|
||||||
if (command.isLocationChanged()) {
|
|
||||||
this.location = command.getLocation();
|
|
||||||
}
|
|
||||||
if (command.isNameChanged()) {
|
|
||||||
this.name = command.getName();
|
|
||||||
}
|
|
||||||
if (command.isSizeChanged()) {
|
|
||||||
this.size = command.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParentEntityType() {
|
|
||||||
return parentEntityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParentEntityType(String parentEntityType) {
|
|
||||||
this.parentEntityType = parentEntityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getParentEntityId() {
|
|
||||||
return parentEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParentEntityId(Long parentEntityId) {
|
|
||||||
this.parentEntityId = parentEntityId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFileName(String fileName) {
|
|
||||||
this.fileName = fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(Long size) {
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(String location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.domain;
|
|
||||||
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
|
||||||
|
|
||||||
public interface DocumentRepository extends
|
|
||||||
JpaRepository<Document, Long>, JpaSpecificationExecutor<Document> {
|
|
||||||
// no added behaviour
|
|
||||||
}
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.service;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.mifosng.platform.api.commands.DocumentCommand;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
|
||||||
|
|
||||||
public class DocumentCommandValidator {
|
|
||||||
|
|
||||||
private final DocumentCommand command;
|
|
||||||
|
|
||||||
public DocumentCommandValidator(DocumentCommand command) {
|
|
||||||
this.command = command;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validateForUpdate() {
|
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
|
||||||
|
|
||||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
|
||||||
dataValidationErrors).resource("document");
|
|
||||||
|
|
||||||
baseDataValidator.reset().parameter("name").value(command.getName())
|
|
||||||
.ignoreIfNull().notBlank();
|
|
||||||
baseDataValidator.reset().parameter("size").value(command.getSize())
|
|
||||||
.ignoreIfNull().integerGreaterThanZero();
|
|
||||||
baseDataValidator.reset().parameter("fileName")
|
|
||||||
.value(command.getFileName()).ignoreIfNull().notBlank()
|
|
||||||
.notExceedingLengthOf(250);
|
|
||||||
baseDataValidator.reset().parameter("location")
|
|
||||||
.value(command.getLocation()).ignoreIfNull().notBlank();
|
|
||||||
baseDataValidator.reset().parameter("description")
|
|
||||||
.value(command.getName()).ignoreIfNull()
|
|
||||||
.notExceedingLengthOf(250);
|
|
||||||
|
|
||||||
baseDataValidator.reset().anyOfNotNull(command.getName(),
|
|
||||||
command.getFileName(), command.getDescription(),
|
|
||||||
command.getLocation(), command.getSize());
|
|
||||||
|
|
||||||
if (!dataValidationErrors.isEmpty()) {
|
|
||||||
throw new PlatformApiDataValidationException(
|
|
||||||
"validation.msg.validation.errors.exist",
|
|
||||||
"Validation errors exist.", dataValidationErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validateForCreate() {
|
|
||||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
|
||||||
|
|
||||||
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(
|
|
||||||
dataValidationErrors).resource("document");
|
|
||||||
baseDataValidator.reset().parameter("parentEntityType")
|
|
||||||
.value(command.getParentEntityType()).notBlank()
|
|
||||||
.notExceedingLengthOf(50);
|
|
||||||
baseDataValidator.reset().parameter("parentEntityId")
|
|
||||||
.value(command.getParentEntityId()).integerGreaterThanZero();
|
|
||||||
baseDataValidator.reset().parameter("name").value(command.getName())
|
|
||||||
.notBlank().notExceedingLengthOf(250);
|
|
||||||
baseDataValidator.reset().parameter("size").value(command.getSize())
|
|
||||||
.integerGreaterThanZero();
|
|
||||||
baseDataValidator.reset().parameter("fileName")
|
|
||||||
.value(command.getFileName()).notBlank()
|
|
||||||
.notExceedingLengthOf(250);
|
|
||||||
baseDataValidator.reset().parameter("description")
|
|
||||||
.value(command.getName()).notExceedingLengthOf(250);
|
|
||||||
|
|
||||||
if (!dataValidationErrors.isEmpty()) {
|
|
||||||
throw new PlatformApiDataValidationException(
|
|
||||||
"validation.msg.validation.errors.exist",
|
|
||||||
"Validation errors exist.", dataValidationErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.service;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.mifosng.platform.api.data.DocumentData;
|
|
||||||
|
|
||||||
public interface DocumentReadPlatformService {
|
|
||||||
|
|
||||||
Collection<DocumentData> retrieveAllDocuments(String entityType,
|
|
||||||
Long entityId);
|
|
||||||
|
|
||||||
DocumentData retrieveDocument(String entityType, Long entityId,
|
|
||||||
Long documentId);
|
|
||||||
|
|
||||||
}
|
|
||||||
-107
@@ -1,107 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.service;
|
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.mifosng.platform.api.data.DocumentData;
|
|
||||||
import org.mifosng.platform.exceptions.DocumentNotFoundException;
|
|
||||||
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
|
||||||
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.dao.EmptyResultDataAccessException;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformService {
|
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
// TODO: use these services to check if passed in entities for document
|
|
||||||
// management exists (and ensure appropriate errors are thrown)
|
|
||||||
private final PlatformSecurityContext context;
|
|
||||||
// private final OfficeReadPlatformService officeReadPlatformService;
|
|
||||||
// private final ClientReadPlatformService clientReadPlatformService;
|
|
||||||
// private final LoanReadPlatformService loanReadPlatformService;
|
|
||||||
// private final StaffReadPlatformService staffReadPlatformService;
|
|
||||||
// private final AppUserReadPlatformService appUserReadPlatformService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public DocumentReadPlatformServiceImpl(
|
|
||||||
final PlatformSecurityContext context,
|
|
||||||
final TenantAwareRoutingDataSource dataSource
|
|
||||||
// final OfficeReadPlatformService officeReadPlatformService,
|
|
||||||
// final AppUserReadPlatformService appUserReadPlatformService,
|
|
||||||
// final ClientReadPlatformService clientReadPlatformService,
|
|
||||||
// final LoanReadPlatformService loanReadPlatformService,
|
|
||||||
// final StaffReadPlatformService staffReadPlatformService
|
|
||||||
) {
|
|
||||||
this.context = context;
|
|
||||||
// this.officeReadPlatformService = officeReadPlatformService;
|
|
||||||
// this.appUserReadPlatformService = appUserReadPlatformService;
|
|
||||||
// this.clientReadPlatformService = clientReadPlatformService;
|
|
||||||
// this.loanReadPlatformService = loanReadPlatformService;
|
|
||||||
// this.staffReadPlatformService = staffReadPlatformService;
|
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<DocumentData> retrieveAllDocuments(final String entityType, final Long entityId) {
|
|
||||||
|
|
||||||
context.authenticatedUser();
|
|
||||||
|
|
||||||
// TODO verify if the entities are valid and a user
|
|
||||||
// has data
|
|
||||||
// scope for the particular entities
|
|
||||||
DocumentMapper mapper = new DocumentMapper();
|
|
||||||
String sql = "select " + mapper.schema() + " order by d.id";
|
|
||||||
return this.jdbcTemplate.query(sql, mapper, new Object[] {entityType, entityId});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocumentData retrieveDocument(final String entityType, final Long entityId, final Long documentId) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
context.authenticatedUser();
|
|
||||||
|
|
||||||
// TODO verify if the entities are valid and a
|
|
||||||
// user has data
|
|
||||||
// scope for the particular entities
|
|
||||||
DocumentMapper mapper = new DocumentMapper();
|
|
||||||
String sql = "select " + mapper.schema() + " and d.id=? ";
|
|
||||||
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] {entityType, entityId, documentId });
|
|
||||||
} catch (EmptyResultDataAccessException e) {
|
|
||||||
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class DocumentMapper implements RowMapper<DocumentData> {
|
|
||||||
|
|
||||||
public String schema() {
|
|
||||||
return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, "
|
|
||||||
+ " d.file_name as fileName, d.size as fileSize, d.type as fileType, "
|
|
||||||
+ " d.description as description, d.location as location"
|
|
||||||
+ " from m_document d where d.parent_entity_type=? and d.parent_entity_id=?";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DocumentData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
|
||||||
|
|
||||||
final Long id = JdbcSupport.getLong(rs, "id");
|
|
||||||
final Long parentEntityId = JdbcSupport.getLong(rs, "parentEntityId");
|
|
||||||
final Long fileSize = JdbcSupport.getLong(rs, "fileSize");
|
|
||||||
final String parentEntityType = rs.getString("parentEntityType");
|
|
||||||
final String name = rs.getString("name");
|
|
||||||
final String fileName = rs.getString("fileName");
|
|
||||||
final String fileType = rs.getString("fileType");
|
|
||||||
final String description = rs.getString("description");
|
|
||||||
final String location = rs.getString("location");
|
|
||||||
|
|
||||||
return new DocumentData(id, parentEntityType, parentEntityId, name,
|
|
||||||
fileName, fileSize, fileType, description, location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.service;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.mifosng.platform.api.commands.DocumentCommand;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
|
|
||||||
public interface DocumentWritePlatformService {
|
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_m_guarantor_external')")
|
|
||||||
Long createDocument(DocumentCommand documentCommand, InputStream inputStream);
|
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_m_guarantor_external')")
|
|
||||||
EntityIdentifier updateDocument(DocumentCommand documentCommand,
|
|
||||||
InputStream inputStream);
|
|
||||||
|
|
||||||
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_m_guarantor_external')")
|
|
||||||
EntityIdentifier deleteDocument(DocumentCommand documentCommand);
|
|
||||||
|
|
||||||
}
|
|
||||||
-198
@@ -1,198 +0,0 @@
|
|||||||
package org.mifosng.platform.documentmanagement.service;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.mifosng.platform.api.commands.DocumentCommand;
|
|
||||||
import org.mifosng.platform.documentmanagement.domain.Document;
|
|
||||||
import org.mifosng.platform.documentmanagement.domain.DocumentRepository;
|
|
||||||
import org.mifosng.platform.exceptions.DocumentManagementException;
|
|
||||||
import org.mifosng.platform.exceptions.DocumentNotFoundException;
|
|
||||||
import org.mifosng.platform.exceptions.InvalidEntityTypeForDocumentManagementException;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
|
||||||
import org.mifosplatform.infrastructure.core.service.FileUtils;
|
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.dao.DataIntegrityViolationException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DocumentWritePlatformServiceJpaRepositoryImpl implements
|
|
||||||
DocumentWritePlatformService {
|
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(DocumentWritePlatformServiceJpaRepositoryImpl.class);
|
|
||||||
|
|
||||||
private final PlatformSecurityContext context;
|
|
||||||
private final DocumentRepository documentRepository;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public DocumentWritePlatformServiceJpaRepositoryImpl(
|
|
||||||
final PlatformSecurityContext context,
|
|
||||||
final DocumentRepository documentRepository) {
|
|
||||||
this.context = context;
|
|
||||||
this.documentRepository = documentRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@Override
|
|
||||||
public Long createDocument(final DocumentCommand documentCommand, final InputStream inputStream) {
|
|
||||||
try {
|
|
||||||
context.authenticatedUser();
|
|
||||||
|
|
||||||
DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand);
|
|
||||||
|
|
||||||
validateParentEntityType(documentCommand);
|
|
||||||
|
|
||||||
validator.validateForCreate();
|
|
||||||
|
|
||||||
String fileUploadLocation = FileUtils.generateFileParentDirectory(
|
|
||||||
documentCommand.getParentEntityType(),
|
|
||||||
documentCommand.getParentEntityId());
|
|
||||||
|
|
||||||
/** Recursively create the directory if it does not exist **/
|
|
||||||
if (!new File(fileUploadLocation).isDirectory()) {
|
|
||||||
new File(fileUploadLocation).mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
String fileLocation = FileUtils.saveToFileSystem(inputStream,
|
|
||||||
fileUploadLocation, documentCommand.getFileName());
|
|
||||||
|
|
||||||
Document document = Document.createNew(
|
|
||||||
documentCommand.getParentEntityType(),
|
|
||||||
documentCommand.getParentEntityId(),
|
|
||||||
documentCommand.getName(), documentCommand.getFileName(),
|
|
||||||
documentCommand.getSize(), documentCommand.getType(),
|
|
||||||
documentCommand.getDescription(), fileLocation);
|
|
||||||
|
|
||||||
this.documentRepository.save(document);
|
|
||||||
|
|
||||||
return document.getId();
|
|
||||||
} catch (DataIntegrityViolationException dve) {
|
|
||||||
logger.error(dve.getMessage(), dve);
|
|
||||||
throw new PlatformDataIntegrityException(
|
|
||||||
"error.msg.document.unknown.data.integrity.issue",
|
|
||||||
"Unknown data integrity issue with resource.");
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
logger.error(ioe.getMessage(), ioe);
|
|
||||||
throw new DocumentManagementException(documentCommand.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier updateDocument(final DocumentCommand documentCommand, final InputStream inputStream) {
|
|
||||||
try {
|
|
||||||
context.authenticatedUser();
|
|
||||||
|
|
||||||
String oldLocation = null;
|
|
||||||
DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand);
|
|
||||||
validator.validateForUpdate();
|
|
||||||
// TODO check if entity id is valid and within data scope for the
|
|
||||||
// user
|
|
||||||
Document documentForUpdate = this.documentRepository
|
|
||||||
.findOne(documentCommand.getId());
|
|
||||||
if (documentForUpdate == null) {
|
|
||||||
throw new DocumentNotFoundException(
|
|
||||||
documentCommand.getParentEntityType(),
|
|
||||||
documentCommand.getParentEntityId(),
|
|
||||||
documentCommand.getId());
|
|
||||||
}
|
|
||||||
oldLocation = documentForUpdate.getLocation();
|
|
||||||
// if a new file is also passed in
|
|
||||||
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
|
||||||
String fileUploadLocation = FileUtils
|
|
||||||
.generateFileParentDirectory(
|
|
||||||
documentCommand.getParentEntityType(),
|
|
||||||
documentCommand.getParentEntityId());
|
|
||||||
|
|
||||||
/** Recursively create the directory if it does not exist **/
|
|
||||||
if (!new File(fileUploadLocation).isDirectory()) {
|
|
||||||
new File(fileUploadLocation).mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO replace file system appender with an Amazon S3 appender
|
|
||||||
String fileLocation = FileUtils.saveToFileSystem(inputStream,
|
|
||||||
fileUploadLocation, documentCommand.getFileName());
|
|
||||||
documentCommand.setLocation(fileLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
documentForUpdate.update(documentCommand);
|
|
||||||
|
|
||||||
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
|
||||||
// delete previous file
|
|
||||||
deleteFile(documentCommand.getName(), oldLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.documentRepository.saveAndFlush(documentForUpdate);
|
|
||||||
|
|
||||||
return new EntityIdentifier(documentForUpdate.getId());
|
|
||||||
} catch (DataIntegrityViolationException dve) {
|
|
||||||
logger.error(dve.getMessage(), dve);
|
|
||||||
throw new PlatformDataIntegrityException(
|
|
||||||
"error.msg.document.unknown.data.integrity.issue",
|
|
||||||
"Unknown data integrity issue with resource.");
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
logger.error(ioe.getMessage(), ioe);
|
|
||||||
throw new DocumentManagementException(documentCommand.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@Override
|
|
||||||
public EntityIdentifier deleteDocument(final DocumentCommand documentCommand) {
|
|
||||||
context.authenticatedUser();
|
|
||||||
|
|
||||||
validateParentEntityType(documentCommand);
|
|
||||||
// TODO: Check document is present under this entity Id
|
|
||||||
Document document = this.documentRepository.findOne(documentCommand.getId());
|
|
||||||
if (document == null) {
|
|
||||||
throw new DocumentNotFoundException(
|
|
||||||
documentCommand.getParentEntityType(),
|
|
||||||
documentCommand.getParentEntityId(),
|
|
||||||
documentCommand.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.documentRepository.delete(document);
|
|
||||||
deleteFile(document.getName(), document.getLocation());
|
|
||||||
return new EntityIdentifier(document.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteFile(String documentName, String location) {
|
|
||||||
File fileToBeDeleted = new File(location);
|
|
||||||
boolean fileDeleted = fileToBeDeleted.delete();
|
|
||||||
if (!fileDeleted) {
|
|
||||||
throw new DocumentManagementException(documentName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateParentEntityType(DocumentCommand documentCommand) {
|
|
||||||
if (!checkValidEntityType(documentCommand.getParentEntityType())) {
|
|
||||||
throw new InvalidEntityTypeForDocumentManagementException(
|
|
||||||
documentCommand.getParentEntityType());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean checkValidEntityType(final String entityType) {
|
|
||||||
|
|
||||||
for (DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) {
|
|
||||||
if (entities.name().equalsIgnoreCase(entityType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Entities for document Management **/
|
|
||||||
public static enum DOCUMENT_MANAGEMENT_ENTITY {
|
|
||||||
CLIENTS, CLIENT_IDENTIFIERS, STAFF, LOANS, SAVINGS;
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name().toString().toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
package org.mifosng.platform.exceptions;
|
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
|
||||||
|
|
||||||
|
|
||||||
public class DocumentManagementException extends
|
|
||||||
AbstractPlatformDomainRuleException {
|
|
||||||
|
|
||||||
public DocumentManagementException(final String name) {
|
|
||||||
super("error.msg.document.save", "Error while manipulating file "
|
|
||||||
+ name + " due to a File system / Amazon S3 issue", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DocumentManagementException(final String name, final Long fileSize,
|
|
||||||
final int maxFileSize) {
|
|
||||||
super("error.msg.document.file.too.big",
|
|
||||||
"Unable to save the document with name" + name
|
|
||||||
+ " since its file Size of " + fileSize / (1024 * 1024)
|
|
||||||
+ " MB exceeds the max permissable file size of "
|
|
||||||
+ maxFileSize
|
|
||||||
+ " MB", name, fileSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
package org.mifosng.platform.exceptions;
|
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
|
||||||
|
|
||||||
public class DocumentNotFoundException extends
|
|
||||||
AbstractPlatformResourceNotFoundException {
|
|
||||||
|
|
||||||
public DocumentNotFoundException(final String entityType,
|
|
||||||
final Long entityId, final Long id) {
|
|
||||||
super("error.msg.document.id.invalid", "Document with identifier " + id
|
|
||||||
+ " does not exist for the " + entityType + " with Identifier "
|
|
||||||
+ entityId, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
package org.mifosng.platform.exceptions;
|
|
||||||
|
|
||||||
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link RuntimeException} thrown when document management functionality is
|
|
||||||
* invoked for invalid Entity Types
|
|
||||||
*/
|
|
||||||
public class InvalidEntityTypeForDocumentManagementException extends
|
|
||||||
AbstractPlatformResourceNotFoundException {
|
|
||||||
|
|
||||||
public InvalidEntityTypeForDocumentManagementException(
|
|
||||||
final String entityType) {
|
|
||||||
super("error.documentmanagement.entitytype.invalid",
|
|
||||||
"Document Management is not support for the Entity Type: "
|
|
||||||
+ entityType, entityType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -7,7 +7,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.mifosng.platform.api.data.DepositAccountData;
|
import org.mifosng.platform.api.data.DepositAccountData;
|
||||||
import org.mifosng.platform.api.data.DepositProductData;
|
import org.mifosng.platform.api.data.DepositProductData;
|
||||||
import org.mifosng.platform.api.data.DocumentData;
|
|
||||||
import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData;
|
import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData;
|
||||||
import org.mifosng.platform.api.data.GroupData;
|
import org.mifosng.platform.api.data.GroupData;
|
||||||
import org.mifosng.platform.api.data.GuarantorData;
|
import org.mifosng.platform.api.data.GuarantorData;
|
||||||
@@ -19,6 +18,7 @@ import org.mifosplatform.infrastructure.configuration.data.ConfigurationData;
|
|||||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||||
import org.mifosplatform.infrastructure.office.data.OfficeData;
|
import org.mifosplatform.infrastructure.office.data.OfficeData;
|
||||||
import org.mifosplatform.infrastructure.office.data.OfficeTransactionData;
|
import org.mifosplatform.infrastructure.office.data.OfficeTransactionData;
|
||||||
import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData;
|
import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData;
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.mifosng.platform.api.data.DepositAccountData;
|
import org.mifosng.platform.api.data.DepositAccountData;
|
||||||
import org.mifosng.platform.api.data.DepositProductData;
|
import org.mifosng.platform.api.data.DepositProductData;
|
||||||
import org.mifosng.platform.api.data.DocumentData;
|
|
||||||
import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData;
|
import org.mifosng.platform.api.data.GroupAccountSummaryCollectionData;
|
||||||
import org.mifosng.platform.api.data.GroupData;
|
import org.mifosng.platform.api.data.GroupData;
|
||||||
import org.mifosng.platform.api.data.GuarantorData;
|
import org.mifosng.platform.api.data.GuarantorData;
|
||||||
@@ -17,6 +16,7 @@ import org.mifosplatform.infrastructure.configuration.data.ConfigurationData;
|
|||||||
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
|
||||||
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||||
import org.mifosplatform.infrastructure.office.data.OfficeData;
|
import org.mifosplatform.infrastructure.office.data.OfficeData;
|
||||||
import org.mifosplatform.infrastructure.office.data.OfficeTransactionData;
|
import org.mifosplatform.infrastructure.office.data.OfficeTransactionData;
|
||||||
import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData;
|
import org.mifosplatform.infrastructure.staff.data.BulkTransferLoanOfficerData;
|
||||||
|
|||||||
+1
-1
@@ -9,12 +9,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import org.mifosng.platform.exceptions.DocumentManagementException;
|
|
||||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||||
import org.mifosplatform.infrastructure.core.exception.ImageDataURLNotValidException;
|
import org.mifosplatform.infrastructure.core.exception.ImageDataURLNotValidException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.ImageUploadException;
|
import org.mifosplatform.infrastructure.core.exception.ImageUploadException;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|||||||
+191
@@ -0,0 +1,191 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.api;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.HeaderParam;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.api.ApiConstants;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
|
||||||
|
import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.FileUtils;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.service.DocumentReadPlatformService;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.service.DocumentWritePlatformService;
|
||||||
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.sun.jersey.core.header.FormDataContentDisposition;
|
||||||
|
import com.sun.jersey.multipart.FormDataBodyPart;
|
||||||
|
import com.sun.jersey.multipart.FormDataParam;
|
||||||
|
|
||||||
|
@Path("{entityType}/{entityId}/documents")
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class DocumentManagementApiResource {
|
||||||
|
|
||||||
|
private final String SystemEntityType = "DOCUMENT";
|
||||||
|
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final DocumentReadPlatformService documentReadPlatformService;
|
||||||
|
private final DocumentWritePlatformService documentWritePlatformService;
|
||||||
|
private final PortfolioApiJsonSerializerService apiJsonSerializerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DocumentManagementApiResource(final PlatformSecurityContext context,
|
||||||
|
final DocumentReadPlatformService documentReadPlatformService, final DocumentWritePlatformService documentWritePlatformService,
|
||||||
|
final PortfolioApiJsonSerializerService apiJsonSerializerService) {
|
||||||
|
this.context = context;
|
||||||
|
this.documentReadPlatformService = documentReadPlatformService;
|
||||||
|
this.documentWritePlatformService = documentWritePlatformService;
|
||||||
|
this.apiJsonSerializerService = apiJsonSerializerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String retreiveAllDocuments(@Context final UriInfo uriInfo, @PathParam("entityType") String entityType,
|
||||||
|
@PathParam("entityId") Long entityId) {
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasReadPermission(SystemEntityType);
|
||||||
|
|
||||||
|
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
|
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
final Collection<DocumentData> documentDatas = this.documentReadPlatformService.retrieveAllDocuments(entityType, entityId);
|
||||||
|
|
||||||
|
return this.apiJsonSerializerService.serializeDocumentDataToJson(prettyPrint, responseParameters, documentDatas);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public Response createDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId,
|
||||||
|
@HeaderParam("Content-Length") Long fileSize, @FormDataParam("file") InputStream inputStream,
|
||||||
|
@FormDataParam("file") FormDataContentDisposition fileDetails, @FormDataParam("file") FormDataBodyPart bodyPart,
|
||||||
|
@FormDataParam("name") String name, @FormDataParam("description") String description) {
|
||||||
|
|
||||||
|
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: also need to have a backup and stop reading from stream after
|
||||||
|
* max size is reached to protect against malicious clients
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: need to extract the actual file type and determine if they are
|
||||||
|
* permissable
|
||||||
|
**/
|
||||||
|
DocumentCommand documentCommand = new DocumentCommand(null, null, entityType, entityId, name, fileDetails.getFileName(), fileSize,
|
||||||
|
bodyPart.getMediaType().toString(), description, null);
|
||||||
|
|
||||||
|
Long documentId = this.documentWritePlatformService.createDocument(documentCommand, inputStream);
|
||||||
|
|
||||||
|
return Response.ok().entity(new EntityIdentifier(documentId)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{documentId}")
|
||||||
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public Response updateDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId,
|
||||||
|
@PathParam("documentId") Long documentId, @HeaderParam("Content-Length") Long fileSize,
|
||||||
|
@FormDataParam("file") InputStream inputStream, @FormDataParam("file") FormDataContentDisposition fileDetails,
|
||||||
|
@FormDataParam("file") FormDataBodyPart bodyPart, @FormDataParam("name") String name,
|
||||||
|
@FormDataParam("description") String description) {
|
||||||
|
|
||||||
|
FileUtils.validateFileSizeWithinPermissibleRange(fileSize, name, ApiConstants.MAX_FILE_UPLOAD_SIZE_IN_MB);
|
||||||
|
|
||||||
|
Set<String> modifiedParams = new HashSet<String>();
|
||||||
|
modifiedParams.add("name");
|
||||||
|
modifiedParams.add("description");
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Populate Document command based on whether a file has also been
|
||||||
|
* passed in as a part of the update
|
||||||
|
***/
|
||||||
|
DocumentCommand documentCommand = null;
|
||||||
|
if (inputStream != null && fileDetails.getFileName() != null) {
|
||||||
|
modifiedParams.add("fileName");
|
||||||
|
modifiedParams.add("size");
|
||||||
|
modifiedParams.add("type");
|
||||||
|
modifiedParams.add("location");
|
||||||
|
documentCommand = new DocumentCommand(modifiedParams, documentId, entityType, entityId, name, fileDetails.getFileName(),
|
||||||
|
fileSize, bodyPart.getMediaType().toString(), description, null);
|
||||||
|
} else {
|
||||||
|
documentCommand = new DocumentCommand(modifiedParams, documentId, entityType, entityId, name, null, null, null, description,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
EntityIdentifier identifier = this.documentWritePlatformService.updateDocument(documentCommand, inputStream);
|
||||||
|
|
||||||
|
return Response.ok().entity(identifier).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{documentId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public String getDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId,
|
||||||
|
@PathParam("documentId") Long documentId, @Context final UriInfo uriInfo) {
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasReadPermission(SystemEntityType);
|
||||||
|
|
||||||
|
final Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
|
final boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
|
||||||
|
|
||||||
|
final DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId);
|
||||||
|
|
||||||
|
return this.apiJsonSerializerService.serializeDocumentDataToJson(prettyPrint, responseParameters, documentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{documentId}/attachment")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public Response downloadFile(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId,
|
||||||
|
@PathParam("documentId") Long documentId) {
|
||||||
|
|
||||||
|
context.authenticatedUser().validateHasReadPermission(SystemEntityType);
|
||||||
|
|
||||||
|
DocumentData documentData = this.documentReadPlatformService.retrieveDocument(entityType, entityId, documentId);
|
||||||
|
File file = new File(documentData.fileLocation());
|
||||||
|
ResponseBuilder response = Response.ok(file);
|
||||||
|
response.header("Content-Disposition", "attachment; filename=\"" + documentData.fileName() + "\"");
|
||||||
|
response.header("Content-Type", documentData.contentType());
|
||||||
|
return response.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{documentId}")
|
||||||
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
|
@Produces({ MediaType.APPLICATION_JSON })
|
||||||
|
public Response deleteDocument(@PathParam("entityType") String entityType, @PathParam("entityId") Long entityId,
|
||||||
|
@PathParam("documentId") Long documentId) {
|
||||||
|
|
||||||
|
DocumentCommand documentCommand = new DocumentCommand(null, documentId, entityType, entityId, null, null, null, null, null, null);
|
||||||
|
|
||||||
|
EntityIdentifier documentIdentifier = this.documentWritePlatformService.deleteDocument(documentCommand);
|
||||||
|
|
||||||
|
return Response.ok(documentIdentifier).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
+117
@@ -0,0 +1,117 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.command;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable command for creating or updating details of a client identifier.
|
||||||
|
*/
|
||||||
|
public class DocumentCommand {
|
||||||
|
|
||||||
|
private final Long id;
|
||||||
|
private final String parentEntityType;
|
||||||
|
private final Long parentEntityId;
|
||||||
|
private final String name;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
private Long size;
|
||||||
|
private String type;
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
private final Set<String> modifiedParameters;
|
||||||
|
|
||||||
|
public DocumentCommand(final Set<String> modifiedParameters, final Long id, final String parentEntityType, final Long parentEntityId,
|
||||||
|
final String name, final String fileName, Long size, String type, final String description, String location) {
|
||||||
|
this.modifiedParameters = modifiedParameters;
|
||||||
|
this.id = id;
|
||||||
|
this.parentEntityType = parentEntityType;
|
||||||
|
this.parentEntityId = parentEntityId;
|
||||||
|
this.name = name;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.size = size;
|
||||||
|
this.type = type;
|
||||||
|
this.description = description;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentEntityType() {
|
||||||
|
return parentEntityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getParentEntityId() {
|
||||||
|
return parentEntityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getModifiedParameters() {
|
||||||
|
return modifiedParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(Long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(String location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNameChanged() {
|
||||||
|
return this.modifiedParameters.contains("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFileNameChanged() {
|
||||||
|
return this.modifiedParameters.contains("fileName");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSizeChanged() {
|
||||||
|
return this.modifiedParameters.contains("size");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFileTypeChanged() {
|
||||||
|
return this.modifiedParameters.contains("type");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDescriptionChanged() {
|
||||||
|
return this.modifiedParameters.contains("description");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocationChanged() {
|
||||||
|
return this.modifiedParameters.contains("location");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.command;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||||
|
|
||||||
|
public class DocumentCommandValidator {
|
||||||
|
|
||||||
|
private final DocumentCommand command;
|
||||||
|
|
||||||
|
public DocumentCommandValidator(DocumentCommand command) {
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForUpdate() {
|
||||||
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
|
||||||
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document");
|
||||||
|
|
||||||
|
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank();
|
||||||
|
baseDataValidator.reset().parameter("size").value(command.getSize()).ignoreIfNull().integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter("fileName").value(command.getFileName()).ignoreIfNull().notBlank().notExceedingLengthOf(250);
|
||||||
|
baseDataValidator.reset().parameter("location").value(command.getLocation()).ignoreIfNull().notBlank();
|
||||||
|
baseDataValidator.reset().parameter("description").value(command.getName()).ignoreIfNull().notExceedingLengthOf(250);
|
||||||
|
|
||||||
|
baseDataValidator.reset().anyOfNotNull(command.getName(), command.getFileName(), command.getDescription(), command.getLocation(),
|
||||||
|
command.getSize());
|
||||||
|
|
||||||
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||||
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateForCreate() {
|
||||||
|
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
|
|
||||||
|
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("document");
|
||||||
|
baseDataValidator.reset().parameter("parentEntityType").value(command.getParentEntityType()).notBlank().notExceedingLengthOf(50);
|
||||||
|
baseDataValidator.reset().parameter("parentEntityId").value(command.getParentEntityId()).integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank().notExceedingLengthOf(250);
|
||||||
|
baseDataValidator.reset().parameter("size").value(command.getSize()).integerGreaterThanZero();
|
||||||
|
baseDataValidator.reset().parameter("fileName").value(command.getFileName()).notBlank().notExceedingLengthOf(250);
|
||||||
|
baseDataValidator.reset().parameter("description").value(command.getName()).notExceedingLengthOf(250);
|
||||||
|
|
||||||
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||||
|
"Validation errors exist.", dataValidationErrors); }
|
||||||
|
}
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable data object represent document being managed on platform.
|
||||||
|
*/
|
||||||
|
public class DocumentData {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long id;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String parentEntityType;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long parentEntityId;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String name;
|
||||||
|
private final String fileName;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long size;
|
||||||
|
private final String type;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final String description;
|
||||||
|
private final String location;
|
||||||
|
|
||||||
|
public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
|
||||||
|
final Long size, final String type, final String description, final String location) {
|
||||||
|
this.id = id;
|
||||||
|
this.parentEntityType = parentEntityType;
|
||||||
|
this.parentEntityId = parentEntityId;
|
||||||
|
this.name = name;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.size = size;
|
||||||
|
this.type = type;
|
||||||
|
this.description = description;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String contentType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String fileName() {
|
||||||
|
return this.fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String fileLocation() {
|
||||||
|
return this.location;
|
||||||
|
}
|
||||||
|
}
|
||||||
+145
@@ -0,0 +1,145 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.domain;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||||
|
import org.mifosplatform.infrastructure.user.domain.AppUser;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "m_document")
|
||||||
|
public class Document extends AbstractAuditableCustom<AppUser, Long> {
|
||||||
|
|
||||||
|
@Column(name = "parent_entity_type", length = 50)
|
||||||
|
private String parentEntityType;
|
||||||
|
|
||||||
|
@Column(name = "parent_entity_id", length = 1000)
|
||||||
|
private Long parentEntityId;
|
||||||
|
|
||||||
|
@Column(name = "name", length = 250)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "file_name", length = 250)
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
@Column(name = "size")
|
||||||
|
private Long size;
|
||||||
|
|
||||||
|
@Column(name = "type", length = 50)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Column(name = "description", length = 1000)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Column(name = "location", length = 500)
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
public Document() {}
|
||||||
|
|
||||||
|
public static Document createNew(String parentEntityType, Long parentEntityId, String name, String fileName, Long size, String type,
|
||||||
|
String description, String location) {
|
||||||
|
return new Document(parentEntityType, parentEntityId, name, fileName, size, type, description, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Document(String parentEntityType, Long parentEntityId, String name, String fileName, Long size, String type,
|
||||||
|
String description, String location) {
|
||||||
|
this.parentEntityType = StringUtils.defaultIfEmpty(parentEntityType, null);
|
||||||
|
this.parentEntityId = parentEntityId;
|
||||||
|
this.name = StringUtils.defaultIfEmpty(name, null);
|
||||||
|
this.fileName = StringUtils.defaultIfEmpty(fileName, null);
|
||||||
|
this.size = size;
|
||||||
|
this.type = StringUtils.defaultIfEmpty(type, null);
|
||||||
|
this.description = StringUtils.defaultIfEmpty(description, null);
|
||||||
|
this.location = StringUtils.defaultIfEmpty(location, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(final DocumentCommand command) {
|
||||||
|
if (command.isDescriptionChanged()) {
|
||||||
|
this.description = command.getDescription();
|
||||||
|
}
|
||||||
|
if (command.isFileNameChanged()) {
|
||||||
|
this.fileName = command.getFileName();
|
||||||
|
}
|
||||||
|
if (command.isFileTypeChanged()) {
|
||||||
|
this.type = command.getType();
|
||||||
|
}
|
||||||
|
if (command.isLocationChanged()) {
|
||||||
|
this.location = command.getLocation();
|
||||||
|
}
|
||||||
|
if (command.isNameChanged()) {
|
||||||
|
this.name = command.getName();
|
||||||
|
}
|
||||||
|
if (command.isSizeChanged()) {
|
||||||
|
this.size = command.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParentEntityType() {
|
||||||
|
return parentEntityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentEntityType(String parentEntityType) {
|
||||||
|
this.parentEntityType = parentEntityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getParentEntityId() {
|
||||||
|
return parentEntityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentEntityId(Long parentEntityId) {
|
||||||
|
this.parentEntityId = parentEntityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(Long size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(String location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.domain;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
|
||||||
|
public interface DocumentRepository extends JpaRepository<Document, Long>, JpaSpecificationExecutor<Document> {
|
||||||
|
// no added behaviour
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
|
||||||
|
|
||||||
|
public class DocumentManagementException extends AbstractPlatformDomainRuleException {
|
||||||
|
|
||||||
|
public DocumentManagementException(final String name) {
|
||||||
|
super("error.msg.document.save", "Error while manipulating file " + name + " due to a File system / Amazon S3 issue", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DocumentManagementException(final String name, final Long fileSize, final int maxFileSize) {
|
||||||
|
super("error.msg.document.file.too.big", "Unable to save the document with name" + name + " since its file Size of " + fileSize
|
||||||
|
/ (1024 * 1024) + " MB exceeds the max permissable file size of " + maxFileSize + " MB", name, fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
public class DocumentNotFoundException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public DocumentNotFoundException(final String entityType, final Long entityId, final Long id) {
|
||||||
|
super("error.msg.document.id.invalid", "Document with identifier " + id + " does not exist for the " + entityType
|
||||||
|
+ " with Identifier " + entityId, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.exception;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link RuntimeException} thrown when document management functionality is
|
||||||
|
* invoked for invalid Entity Types
|
||||||
|
*/
|
||||||
|
public class InvalidEntityTypeForDocumentManagementException extends AbstractPlatformResourceNotFoundException {
|
||||||
|
|
||||||
|
public InvalidEntityTypeForDocumentManagementException(final String entityType) {
|
||||||
|
super("error.documentmanagement.entitytype.invalid", "Document Management is not support for the Entity Type: " + entityType,
|
||||||
|
entityType);
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||||
|
|
||||||
|
public interface DocumentReadPlatformService {
|
||||||
|
|
||||||
|
Collection<DocumentData> retrieveAllDocuments(String entityType, Long entityId);
|
||||||
|
|
||||||
|
DocumentData retrieveDocument(String entityType, Long entityId, Long documentId);
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||||
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformService {
|
||||||
|
|
||||||
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DocumentReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) {
|
||||||
|
this.context = context;
|
||||||
|
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<DocumentData> retrieveAllDocuments(final String entityType, final Long entityId) {
|
||||||
|
|
||||||
|
context.authenticatedUser();
|
||||||
|
|
||||||
|
// TODO verify if the entities are valid and a user
|
||||||
|
// has data
|
||||||
|
// scope for the particular entities
|
||||||
|
DocumentMapper mapper = new DocumentMapper();
|
||||||
|
String sql = "select " + mapper.schema() + " order by d.id";
|
||||||
|
return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId });
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DocumentData retrieveDocument(final String entityType, final Long entityId, final Long documentId) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
context.authenticatedUser();
|
||||||
|
|
||||||
|
// TODO verify if the entities are valid and a
|
||||||
|
// user has data
|
||||||
|
// scope for the particular entities
|
||||||
|
DocumentMapper mapper = new DocumentMapper();
|
||||||
|
String sql = "select " + mapper.schema() + " and d.id=? ";
|
||||||
|
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { entityType, entityId, documentId });
|
||||||
|
} catch (EmptyResultDataAccessException e) {
|
||||||
|
throw new DocumentNotFoundException(entityType, entityId, documentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class DocumentMapper implements RowMapper<DocumentData> {
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return "d.id as id, d.parent_entity_type as parentEntityType, d.parent_entity_id as parentEntityId, d.name as name, "
|
||||||
|
+ " d.file_name as fileName, d.size as fileSize, d.type as fileType, "
|
||||||
|
+ " d.description as description, d.location as location"
|
||||||
|
+ " from m_document d where d.parent_entity_type=? and d.parent_entity_id=?";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DocumentData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
|
||||||
|
|
||||||
|
final Long id = JdbcSupport.getLong(rs, "id");
|
||||||
|
final Long parentEntityId = JdbcSupport.getLong(rs, "parentEntityId");
|
||||||
|
final Long fileSize = JdbcSupport.getLong(rs, "fileSize");
|
||||||
|
final String parentEntityType = rs.getString("parentEntityType");
|
||||||
|
final String name = rs.getString("name");
|
||||||
|
final String fileName = rs.getString("fileName");
|
||||||
|
final String fileType = rs.getString("fileType");
|
||||||
|
final String description = rs.getString("description");
|
||||||
|
final String location = rs.getString("location");
|
||||||
|
|
||||||
|
return new DocumentData(id, parentEntityType, parentEntityId, name, fileName, fileSize, fileType, description, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
|
public interface DocumentWritePlatformService {
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_m_guarantor_external')")
|
||||||
|
Long createDocument(DocumentCommand documentCommand, InputStream inputStream);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_m_guarantor_external')")
|
||||||
|
EntityIdentifier updateDocument(DocumentCommand documentCommand, InputStream inputStream);
|
||||||
|
|
||||||
|
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_m_guarantor_external')")
|
||||||
|
EntityIdentifier deleteDocument(DocumentCommand documentCommand);
|
||||||
|
|
||||||
|
}
|
||||||
+172
@@ -0,0 +1,172 @@
|
|||||||
|
package org.mifosplatform.infrastructure.documentmanagement.service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
||||||
|
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.FileUtils;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommandValidator;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.domain.Document;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.domain.DocumentRepository;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentNotFoundException;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.InvalidEntityTypeForDocumentManagementException;
|
||||||
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DocumentWritePlatformServiceJpaRepositoryImpl implements DocumentWritePlatformService {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(DocumentWritePlatformServiceJpaRepositoryImpl.class);
|
||||||
|
|
||||||
|
private final PlatformSecurityContext context;
|
||||||
|
private final DocumentRepository documentRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DocumentWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DocumentRepository documentRepository) {
|
||||||
|
this.context = context;
|
||||||
|
this.documentRepository = documentRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public Long createDocument(final DocumentCommand documentCommand, final InputStream inputStream) {
|
||||||
|
try {
|
||||||
|
context.authenticatedUser();
|
||||||
|
|
||||||
|
DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand);
|
||||||
|
|
||||||
|
validateParentEntityType(documentCommand);
|
||||||
|
|
||||||
|
validator.validateForCreate();
|
||||||
|
|
||||||
|
String fileUploadLocation = FileUtils.generateFileParentDirectory(documentCommand.getParentEntityType(),
|
||||||
|
documentCommand.getParentEntityId());
|
||||||
|
|
||||||
|
/** Recursively create the directory if it does not exist **/
|
||||||
|
if (!new File(fileUploadLocation).isDirectory()) {
|
||||||
|
new File(fileUploadLocation).mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileLocation = FileUtils.saveToFileSystem(inputStream, fileUploadLocation, documentCommand.getFileName());
|
||||||
|
|
||||||
|
Document document = Document.createNew(documentCommand.getParentEntityType(), documentCommand.getParentEntityId(),
|
||||||
|
documentCommand.getName(), documentCommand.getFileName(), documentCommand.getSize(), documentCommand.getType(),
|
||||||
|
documentCommand.getDescription(), fileLocation);
|
||||||
|
|
||||||
|
this.documentRepository.save(document);
|
||||||
|
|
||||||
|
return document.getId();
|
||||||
|
} catch (DataIntegrityViolationException dve) {
|
||||||
|
logger.error(dve.getMessage(), dve);
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
||||||
|
"Unknown data integrity issue with resource.");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
logger.error(ioe.getMessage(), ioe);
|
||||||
|
throw new DocumentManagementException(documentCommand.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public EntityIdentifier updateDocument(final DocumentCommand documentCommand, final InputStream inputStream) {
|
||||||
|
try {
|
||||||
|
context.authenticatedUser();
|
||||||
|
|
||||||
|
String oldLocation = null;
|
||||||
|
DocumentCommandValidator validator = new DocumentCommandValidator(documentCommand);
|
||||||
|
validator.validateForUpdate();
|
||||||
|
// TODO check if entity id is valid and within data scope for the
|
||||||
|
// user
|
||||||
|
Document documentForUpdate = this.documentRepository.findOne(documentCommand.getId());
|
||||||
|
if (documentForUpdate == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
||||||
|
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
||||||
|
oldLocation = documentForUpdate.getLocation();
|
||||||
|
// if a new file is also passed in
|
||||||
|
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
||||||
|
String fileUploadLocation = FileUtils.generateFileParentDirectory(documentCommand.getParentEntityType(),
|
||||||
|
documentCommand.getParentEntityId());
|
||||||
|
|
||||||
|
/** Recursively create the directory if it does not exist **/
|
||||||
|
if (!new File(fileUploadLocation).isDirectory()) {
|
||||||
|
new File(fileUploadLocation).mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO replace file system appender with an Amazon S3 appender
|
||||||
|
String fileLocation = FileUtils.saveToFileSystem(inputStream, fileUploadLocation, documentCommand.getFileName());
|
||||||
|
documentCommand.setLocation(fileLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
documentForUpdate.update(documentCommand);
|
||||||
|
|
||||||
|
if (inputStream != null && documentCommand.isFileNameChanged()) {
|
||||||
|
// delete previous file
|
||||||
|
deleteFile(documentCommand.getName(), oldLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.documentRepository.saveAndFlush(documentForUpdate);
|
||||||
|
|
||||||
|
return new EntityIdentifier(documentForUpdate.getId());
|
||||||
|
} catch (DataIntegrityViolationException dve) {
|
||||||
|
logger.error(dve.getMessage(), dve);
|
||||||
|
throw new PlatformDataIntegrityException("error.msg.document.unknown.data.integrity.issue",
|
||||||
|
"Unknown data integrity issue with resource.");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
logger.error(ioe.getMessage(), ioe);
|
||||||
|
throw new DocumentManagementException(documentCommand.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public EntityIdentifier deleteDocument(final DocumentCommand documentCommand) {
|
||||||
|
context.authenticatedUser();
|
||||||
|
|
||||||
|
validateParentEntityType(documentCommand);
|
||||||
|
// TODO: Check document is present under this entity Id
|
||||||
|
Document document = this.documentRepository.findOne(documentCommand.getId());
|
||||||
|
if (document == null) { throw new DocumentNotFoundException(documentCommand.getParentEntityType(),
|
||||||
|
documentCommand.getParentEntityId(), documentCommand.getId()); }
|
||||||
|
|
||||||
|
this.documentRepository.delete(document);
|
||||||
|
deleteFile(document.getName(), document.getLocation());
|
||||||
|
return new EntityIdentifier(document.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteFile(String documentName, String location) {
|
||||||
|
File fileToBeDeleted = new File(location);
|
||||||
|
boolean fileDeleted = fileToBeDeleted.delete();
|
||||||
|
if (!fileDeleted) { throw new DocumentManagementException(documentName); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateParentEntityType(DocumentCommand documentCommand) {
|
||||||
|
if (!checkValidEntityType(documentCommand.getParentEntityType())) { throw new InvalidEntityTypeForDocumentManagementException(
|
||||||
|
documentCommand.getParentEntityType()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkValidEntityType(final String entityType) {
|
||||||
|
|
||||||
|
for (DOCUMENT_MANAGEMENT_ENTITY entities : DOCUMENT_MANAGEMENT_ENTITY.values()) {
|
||||||
|
if (entities.name().equalsIgnoreCase(entityType)) { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Entities for document Management **/
|
||||||
|
public static enum DOCUMENT_MANAGEMENT_ENTITY {
|
||||||
|
CLIENTS, CLIENT_IDENTIFIERS, STAFF, LOANS, SAVINGS;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name().toString().toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -5,7 +5,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.mifosng.platform.exceptions.DocumentManagementException;
|
|
||||||
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
|
||||||
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
|
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
|
||||||
import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException;
|
import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException;
|
||||||
@@ -14,6 +13,7 @@ import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
|
|||||||
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
|
||||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||||
import org.mifosplatform.infrastructure.core.service.FileUtils;
|
import org.mifosplatform.infrastructure.core.service.FileUtils;
|
||||||
|
import org.mifosplatform.infrastructure.documentmanagement.exception.DocumentManagementException;
|
||||||
import org.mifosplatform.infrastructure.office.domain.Office;
|
import org.mifosplatform.infrastructure.office.domain.Office;
|
||||||
import org.mifosplatform.infrastructure.office.domain.OfficeRepository;
|
import org.mifosplatform.infrastructure.office.domain.OfficeRepository;
|
||||||
import org.mifosplatform.infrastructure.office.exception.OfficeNotFoundException;
|
import org.mifosplatform.infrastructure.office.exception.OfficeNotFoundException;
|
||||||
|
|||||||
Reference in New Issue
Block a user