ContentRepository.fetchImage() FileData not ImageData (FINERACT-1201)

This is more consistent with fetchFile(), and allows to re-use code.
This commit is contained in:
Michael Vorburger
2020-11-19 10:25:32 +01:00
committed by Percy Enoabane
parent 3e1444a6e4
commit 6c853a6cc7
15 changed files with 148 additions and 161 deletions
@@ -0,0 +1,61 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.infrastructure.documentmanagement.api;
import com.google.common.io.ByteSource;
import java.io.IOException;
import java.io.InputStream;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import org.apache.fineract.infrastructure.documentmanagement.data.FileData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utilities common to file upload/download resources.
*
* @author Michael Vorburger.ch
*/
final class ContentResources {
private static final Logger LOG = LoggerFactory.getLogger(ContentResources.class);
private ContentResources() {}
static Response fileDataToResponse(FileData fileData, String fileName, String dispositionType) {
ResponseBuilder response;
try {
ByteSource byteSource = fileData.getByteSource();
// TODO Where is this InputStream closed?! It needs to be AFTER it's read by JAX-RS.. how to do that?
InputStream is = byteSource.openBufferedStream();
response = Response.ok(is);
response.header("Content-Disposition", dispositionType + "; filename=\"" + fileName + "\"");
response.header("Content-Length", byteSource.sizeIfKnown().or(-1L));
response.header("Content-Type", fileData.contentType());
} catch (IOException e) {
LOG.error("resizedImage.getByteSource().openBufferedStream() failed", e);
response = Response.serverError();
}
return response.build();
}
static Response fileDataToResponse(FileData fileData, String dispositionType) {
return fileDataToResponse(fileData, fileData.name(), dispositionType);
}
}
@@ -46,7 +46,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper; import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
@@ -225,13 +224,8 @@ public class DocumentManagementApiResource {
@PathParam("documentId") @Parameter(description = "documentId") final Long documentId) { @PathParam("documentId") @Parameter(description = "documentId") final Long documentId) {
this.context.authenticatedUser().validateHasReadPermission(this.systemEntityType); this.context.authenticatedUser().validateHasReadPermission(this.systemEntityType);
final FileData fileData = this.documentReadPlatformService.retrieveFileData(entityType, entityId, documentId); final FileData fileData = this.documentReadPlatformService.retrieveFileData(entityType, entityId, documentId);
final ResponseBuilder response = Response.ok(fileData.inputStream()); return ContentResources.fileDataToResponse(fileData, "attachment");
response.header("Content-Disposition", "attachment; filename=\"" + fileData.name() + "\"");
response.header("Content-Type", fileData.contentType());
return response.build();
} }
@DELETE @DELETE
@@ -18,7 +18,6 @@
*/ */
package org.apache.fineract.infrastructure.documentmanagement.api; package org.apache.fineract.infrastructure.documentmanagement.api;
import com.google.common.io.ByteSource;
import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart; import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataParam; import com.sun.jersey.multipart.FormDataParam;
@@ -37,14 +36,13 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage; import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension;
import org.apache.fineract.infrastructure.documentmanagement.data.ImageData; import org.apache.fineract.infrastructure.documentmanagement.data.FileData;
import org.apache.fineract.infrastructure.documentmanagement.data.ImageResizer; import org.apache.fineract.infrastructure.documentmanagement.data.ImageResizer;
import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException; import org.apache.fineract.infrastructure.documentmanagement.exception.ContentManagementException;
import org.apache.fineract.infrastructure.documentmanagement.exception.InvalidEntityTypeForImageManagementException; import org.apache.fineract.infrastructure.documentmanagement.exception.InvalidEntityTypeForImageManagementException;
@@ -52,8 +50,6 @@ import org.apache.fineract.infrastructure.documentmanagement.service.ImageReadPl
import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService; import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.portfolio.client.data.ClientData; import org.apache.fineract.portfolio.client.data.ClientData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -63,8 +59,6 @@ import org.springframework.stereotype.Component;
@Path("{entity}/{entityId}/images") @Path("{entity}/{entityId}/images")
public class ImagesApiResource { public class ImagesApiResource {
private static final Logger LOG = LoggerFactory.getLogger(ImagesApiResource.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ImageReadPlatformService imageReadPlatformService; private final ImageReadPlatformService imageReadPlatformService;
private final ImageWritePlatformService imageWritePlatformService; private final ImageWritePlatformService imageWritePlatformService;
@@ -144,23 +138,23 @@ public class ImagesApiResource {
return downloadClientImage(entityName, entityId, maxWidth, maxHeight, output); return downloadClientImage(entityName, entityId, maxWidth, maxHeight, output);
} }
final ImageData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId); final FileData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId);
// TODO: Need a better way of determining image type // TODO: Need a better way of determining image type
String imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.JPEG.getValue(); String imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.JPEG.getValue();
if (StringUtils.endsWith(imageData.location(), ContentRepositoryUtils.ImageFileExtension.GIF.getValue())) { if (StringUtils.endsWith(imageData.name(), ContentRepositoryUtils.ImageFileExtension.GIF.getValue())) {
imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.GIF.getValue(); imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.GIF.getValue();
} else if (StringUtils.endsWith(imageData.location(), ContentRepositoryUtils.ImageFileExtension.PNG.getValue())) { } else if (StringUtils.endsWith(imageData.name(), ContentRepositoryUtils.ImageFileExtension.PNG.getValue())) {
imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.PNG.getValue(); imageDataURISuffix = ContentRepositoryUtils.ImageDataURIsuffix.PNG.getValue();
} }
ImageData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight); FileData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight);
try { try {
byte[] resizedImageBytes = resizedImage.getByteSource().read(); byte[] resizedImageBytes = resizedImage.getByteSource().read();
final String clientImageAsBase64Text = imageDataURISuffix + Base64.getMimeEncoder().encodeToString(resizedImageBytes); final String clientImageAsBase64Text = imageDataURISuffix + Base64.getMimeEncoder().encodeToString(resizedImageBytes);
return Response.ok(clientImageAsBase64Text).build(); return Response.ok(clientImageAsBase64Text).build();
} catch (IOException e) { } catch (IOException e) {
throw new ContentManagementException(imageData.getEntityDisplayName(), e.getMessage(), e); throw new ContentManagementException(imageData.name(), e.getMessage(), e);
} }
} }
@@ -177,25 +171,10 @@ public class ImagesApiResource {
this.context.authenticatedUser().validateHasReadPermission("STAFFIMAGE"); this.context.authenticatedUser().validateHasReadPermission("STAFFIMAGE");
} }
final ImageData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId); final FileData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId);
final ImageData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight); final FileData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight);
ResponseBuilder response; return ContentResources.fileDataToResponse(resizedImage, resizedImage.name() + ImageFileExtension.JPEG,
try { "inline_octet".equals(output) ? "inline" : "attachment");
ByteSource byteSource = resizedImage.getByteSource();
// TODO Where is this InputStream closed?! It needs to be AFTER it's read by JAX-RS.. how to do that?
InputStream is = byteSource.openBufferedStream();
response = Response.ok(is);
final String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment";
response.header("Content-Disposition",
dispositionType + "; filename=\"" + imageData.getEntityDisplayName() + ImageFileExtension.JPEG + "\"");
response.header("Content-Length", byteSource.sizeIfKnown().or(-1L));
// TODO: Need a better way of determining image type
response.header("Content-Type", imageData.contentType());
} catch (IOException e) {
LOG.error("resizedImage.getByteSource().openBufferedStream() failed", e);
response = Response.serverError();
}
return response.build();
} }
/** /**
@@ -49,7 +49,7 @@ public interface ContentRepository {
void deleteImage(String location); void deleteImage(String location);
ImageData fetchImage(ImageData imageData); FileData fetchImage(ImageData imageData);
StorageType getStorageType(); StorageType getStorageType();
@@ -113,14 +113,24 @@ public final class ContentRepositoryUtils {
} }
} }
public static ImageFileExtension imageExtensionFromFileName(String fileName) {
if (StringUtils.endsWith(fileName.toLowerCase(), ContentRepositoryUtils.ImageFileExtension.GIF.getValue())) {
return ContentRepositoryUtils.ImageFileExtension.GIF;
} else if (StringUtils.endsWith(fileName, ContentRepositoryUtils.ImageFileExtension.PNG.getValue())) {
return ContentRepositoryUtils.ImageFileExtension.PNG;
} else {
return ContentRepositoryUtils.ImageFileExtension.JPEG;
}
}
/** /**
* Validates that passed in Mime type maps to known image mime types * Validates that passed in Mime type maps to known image mime types
* *
* @param mimeType * @param mimeType
*/ */
public static void validateImageMimeType(final String mimeType) { public static void validateImageMimeType(final String mimeType) {
if (!(mimeType.equalsIgnoreCase(ImageMIMEtype.GIF.getValue()) || mimeType.equalsIgnoreCase(ImageMIMEtype.JPEG.getValue()) if ((!mimeType.equalsIgnoreCase(ImageMIMEtype.GIF.getValue()) && !mimeType.equalsIgnoreCase(ImageMIMEtype.JPEG.getValue())
|| mimeType.equalsIgnoreCase(ImageMIMEtype.PNG.getValue()))) { && !mimeType.equalsIgnoreCase(ImageMIMEtype.PNG.getValue()))) {
throw new ImageUploadException(mimeType); throw new ImageUploadException(mimeType);
} }
} }
@@ -99,14 +99,13 @@ public class FileSystemContentRepository implements ContentRepository {
@Override @Override
public FileData fetchFile(final DocumentData documentData) { public FileData fetchFile(final DocumentData documentData) {
final File file = new File(documentData.fileLocation()); final File file = new File(documentData.fileLocation());
return new FileData(file, documentData.fileName(), documentData.contentType()); return new FileData(Files.asByteSource(file), documentData.fileName(), documentData.contentType());
} }
@Override @Override
public ImageData fetchImage(final ImageData imageData) { public FileData fetchImage(final ImageData imageData) {
final File file = new File(imageData.location()); final File file = new File(imageData.location());
imageData.updateContent(file); return new FileData(Files.asByteSource(file), imageData.getEntityDisplayName(), imageData.contentType().getValue());
return imageData;
} }
@Override @Override
@@ -105,21 +105,26 @@ public class S3ContentRepository implements ContentRepository {
@Override @Override
public FileData fetchFile(final DocumentData documentData) throws DocumentNotFoundException { public FileData fetchFile(final DocumentData documentData) throws DocumentNotFoundException {
final S3Object s3object = getObject(documentData.fileLocation()); return new FileData(new ByteSource() {
return new FileData(s3object.getObjectContent(), documentData.fileName(), documentData.contentType());
@Override
public InputStream openStream() throws IOException {
final S3Object s3object = getObject(documentData.fileLocation());
return s3object.getObjectContent();
}
}, documentData.fileName(), documentData.contentType());
} }
@Override @Override
public ImageData fetchImage(final ImageData imageData) { public FileData fetchImage(final ImageData imageData) {
imageData.updateContent(new ByteSource() { return new FileData(new ByteSource() {
@Override @Override
public InputStream openStream() throws IOException { public InputStream openStream() throws IOException {
final S3Object s3object = getObject(imageData.location()); final S3Object s3object = getObject(imageData.location());
return s3object.getObjectContent(); return s3object.getObjectContent();
} }
}); }, imageData.getEntityDisplayName(), imageData.contentType().getValue());
return imageData;
} }
@Override @Override
@@ -21,22 +21,19 @@ package org.apache.fineract.infrastructure.documentmanagement.data;
import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
/** /**
* Immutable data object represent document being managed on platform. * Immutable data object representing a user document being managed on the platform.
*/ */
public class DocumentData { public class DocumentData {
private final Long id; private final Long id;
private final String parentEntityType; private final String parentEntityType;
private final Long parentEntityId; private final Long parentEntityId;
@SuppressWarnings("unused")
private final String name; private final String name;
private final String fileName; private final String fileName;
@SuppressWarnings("unused")
private final Long size; private final Long size;
private final String type; private final String type;
@SuppressWarnings("unused")
private final String description;
private final String location; private final String location;
private final String description;
private final Integer storageType; private final Integer storageType;
public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName, public DocumentData(final Long id, final String parentEntityType, final Long parentEntityId, final String name, final String fileName,
@@ -81,4 +78,15 @@ public class DocumentData {
return this.id; return this.id;
} }
public String getName() {
return this.name;
}
public String getDescription() {
return this.description;
}
public Long getSize() {
return this.size;
}
} }
@@ -18,34 +18,18 @@
*/ */
package org.apache.fineract.infrastructure.documentmanagement.data; package org.apache.fineract.infrastructure.documentmanagement.data;
import java.io.File; import com.google.common.io.ByteSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileData { public class FileData {
private static final Logger LOG = LoggerFactory.getLogger(FileData.class);
private final File file;
private final String fileName; private final String fileName;
private final String contentType; private final String contentType;
private final InputStream inputStream; private final ByteSource byteSource;
public FileData(final File file, final String fileName, final String contentType) { public FileData(final ByteSource byteSource, final String fileName, final String contentType) {
this.file = file;
this.fileName = fileName;
this.contentType = contentType;
this.inputStream = null;
}
public FileData(final InputStream inputStream, final String fileName, final String contentType) {
this.file = null;
this.inputStream = inputStream;
this.fileName = fileName; this.fileName = fileName;
this.contentType = contentType; this.contentType = contentType;
this.byteSource = byteSource;
} }
public String contentType() { public String contentType() {
@@ -56,15 +40,7 @@ public class FileData {
return this.fileName; return this.fileName;
} }
public InputStream inputStream() { public ByteSource getByteSource() {
try { return this.byteSource;
if (this.inputStream == null) {
return new FileInputStream(this.file);
}
return this.inputStream;
} catch (final FileNotFoundException e) {
LOG.error("Error occured.", e);
return null;
}
} }
} }
@@ -18,11 +18,8 @@
*/ */
package org.apache.fineract.infrastructure.documentmanagement.data; package org.apache.fineract.infrastructure.documentmanagement.data;
import com.google.common.io.ByteSource;
import com.google.common.io.Files;
import java.io.File;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageMIMEtype;
import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
public class ImageData { public class ImageData {
@@ -30,61 +27,24 @@ public class ImageData {
private final String location; private final String location;
private final StorageType storageType; private final StorageType storageType;
private final String entityDisplayName; private final String entityDisplayName;
private final ContentRepositoryUtils.ImageMIMEtype contentType;
private File file;
private ByteSource byteSource;
private ContentRepositoryUtils.ImageFileExtension fileExtension;
public ImageData(final String location, final StorageType storageType, final String entityDisplayName) { public ImageData(final String location, final StorageType storageType, final String entityDisplayName) {
this.location = location; this.location = location;
this.storageType = storageType; this.storageType = storageType;
this.entityDisplayName = entityDisplayName; this.entityDisplayName = entityDisplayName;
this.contentType = ContentRepositoryUtils.ImageMIMEtype
.fromFileExtension(ContentRepositoryUtils.imageExtensionFromFileName(location));
} }
private void setImageFileExtension(String filename) { public ImageMIMEtype contentType() {
fileExtension = ContentRepositoryUtils.ImageFileExtension.JPEG; return this.contentType;
if (StringUtils.endsWith(filename.toLowerCase(), ContentRepositoryUtils.ImageFileExtension.GIF.getValue())) {
fileExtension = ContentRepositoryUtils.ImageFileExtension.GIF;
} else if (StringUtils.endsWith(filename, ContentRepositoryUtils.ImageFileExtension.PNG.getValue())) {
fileExtension = ContentRepositoryUtils.ImageFileExtension.PNG;
}
}
public void updateContent(final File file) {
this.file = file;
if (this.file != null) {
setImageFileExtension(this.file.getName());
}
}
public void updateContent(final ByteSource byteSource) {
this.byteSource = byteSource;
}
public ByteSource getByteSource() {
if (this.file != null) {
return Files.asByteSource(file);
}
return this.byteSource;
}
public String contentType() {
return ContentRepositoryUtils.ImageMIMEtype.fromFileExtension(this.fileExtension).getValue();
}
public ContentRepositoryUtils.ImageFileExtension getFileExtension() {
return this.fileExtension;
} }
public StorageType storageType() { public StorageType storageType() {
return this.storageType; return this.storageType;
} }
public String name() {
return this.file.getName();
}
public String location() { public String location() {
return this.location; return this.location;
} }
@@ -40,28 +40,27 @@ public class ImageResizer {
private static final Logger LOG = LoggerFactory.getLogger(ImageResizer.class); private static final Logger LOG = LoggerFactory.getLogger(ImageResizer.class);
public ImageData resize(ImageData image, Integer maxWidth, Integer maxHeight) { public FileData resize(FileData fileData, Integer maxWidth, Integer maxHeight) {
if (maxWidth == null && maxHeight != null) { if (maxWidth == null && maxHeight != null) {
return image; return fileData;
} }
try (InputStream is = image.getByteSource().openBufferedStream()) { try (InputStream is = fileData.getByteSource().openBufferedStream()) {
Optional<InputStream> optResizedIS = resizeImage(image.getFileExtension(), is, maxWidth != null ? maxWidth : Integer.MAX_VALUE, Optional<InputStream> optResizedIS = resizeImage(ContentRepositoryUtils.imageExtensionFromFileName(fileData.name()), is,
maxHeight != null ? maxHeight : Integer.MAX_VALUE); maxWidth != null ? maxWidth : Integer.MAX_VALUE, maxHeight != null ? maxHeight : Integer.MAX_VALUE);
if (optResizedIS.isPresent()) { if (optResizedIS.isPresent()) {
ImageData resizedImage = new ImageData(image.location(), image.storageType(), image.getEntityDisplayName()); FileData resizedImage = new FileData(new ByteSource() {
resizedImage.updateContent(new ByteSource() {
@Override @Override
public InputStream openStream() throws IOException { public InputStream openStream() throws IOException {
return optResizedIS.get(); return optResizedIS.get();
} }
}); }, fileData.name(), fileData.contentType());
return resizedImage; return resizedImage;
} }
return image; return fileData;
} catch (IOException e) { } catch (IOException e) {
LOG.warn("resize() failed, returning original image: {}", e.getMessage(), e); LOG.warn("resize() failed, returning original image: {}", e.getMessage(), e);
return image; return fileData;
} }
} }
@@ -60,7 +60,7 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
// scope for the particular entities // scope for the particular entities
final DocumentMapper mapper = new DocumentMapper(true, true); final DocumentMapper mapper = new DocumentMapper(true, true);
final String sql = "select " + mapper.schema() + " order by d.id"; final String sql = "select " + mapper.schema() + " order by d.id";
return this.jdbcTemplate.query(sql, mapper, new Object[] { entityType, entityId }); return this.jdbcTemplate.query(sql, mapper, entityType, entityId);
} }
@Override @Override
@@ -85,17 +85,10 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
} }
} }
/**
* @param entityType
* @param entityId
* @param documentId
* @param mapper
* @return
*/
private DocumentData fetchDocumentDetails(final String entityType, final Long entityId, final Long documentId, private DocumentData fetchDocumentDetails(final String entityType, final Long entityId, final Long documentId,
final DocumentMapper mapper) { final DocumentMapper mapper) {
final String sql = "select " + mapper.schema() + " and d.id=? "; final String sql = "select " + mapper.schema() + " and d.id=? ";
return this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { entityType, entityId, documentId }); return this.jdbcTemplate.queryForObject(sql, mapper, entityType, entityId, documentId);
} }
private static final class DocumentMapper implements RowMapper<DocumentData> { private static final class DocumentMapper implements RowMapper<DocumentData> {
@@ -117,7 +110,6 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
@Override @Override
public DocumentData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { public DocumentData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
final Long parentEntityId = JdbcSupport.getLong(rs, "parentEntityId"); final Long parentEntityId = JdbcSupport.getLong(rs, "parentEntityId");
final Long fileSize = JdbcSupport.getLong(rs, "fileSize"); final Long fileSize = JdbcSupport.getLong(rs, "fileSize");
@@ -138,5 +130,4 @@ public class DocumentReadPlatformServiceImpl implements DocumentReadPlatformServ
storageType); storageType);
} }
} }
} }
@@ -18,10 +18,10 @@
*/ */
package org.apache.fineract.infrastructure.documentmanagement.service; package org.apache.fineract.infrastructure.documentmanagement.service;
import org.apache.fineract.infrastructure.documentmanagement.data.ImageData; import org.apache.fineract.infrastructure.documentmanagement.data.FileData;
public interface ImageReadPlatformService { public interface ImageReadPlatformService {
ImageData retrieveImage(String entityType, Long entityId); FileData retrieveImage(String entityType, Long entityId);
} }
@@ -25,6 +25,7 @@ import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.documentmanagement.api.ImagesApiResource.EntityTypeForImages; import org.apache.fineract.infrastructure.documentmanagement.api.ImagesApiResource.EntityTypeForImages;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepository; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepository;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory; import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryFactory;
import org.apache.fineract.infrastructure.documentmanagement.data.FileData;
import org.apache.fineract.infrastructure.documentmanagement.data.ImageData; import org.apache.fineract.infrastructure.documentmanagement.data.ImageData;
import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType; import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
import org.apache.fineract.organisation.staff.domain.Staff; import org.apache.fineract.organisation.staff.domain.Staff;
@@ -84,7 +85,7 @@ public class ImageReadPlatformServiceImpl implements ImageReadPlatformService {
} }
@Override @Override
public ImageData retrieveImage(String entityType, final Long entityId) { public FileData retrieveImage(String entityType, final Long entityId) {
try { try {
String displayName; String displayName;
if (EntityTypeForImages.CLIENTS.toString().equalsIgnoreCase(entityType)) { if (EntityTypeForImages.CLIENTS.toString().equalsIgnoreCase(entityType)) {
@@ -52,7 +52,7 @@ public class DocumentTest extends IntegrationTest {
void createDocument() { void createDocument() {
String name = "Test"; String name = "Test";
Part part = Parts.fromFile(testFile); Part part = Parts.fromFile(testFile);
String description = null; String description = "The Description";
var response = ok(fineract().documents.createDocument("clients", clientId, part, name, description)); var response = ok(fineract().documents.createDocument("clients", clientId, part, name, description));
assertThat(response.getResourceId()).isNotNull(); assertThat(response.getResourceId()).isNotNull();
assertThat(response.getResourceIdentifier()).isNotEmpty(); assertThat(response.getResourceIdentifier()).isNotEmpty();
@@ -65,12 +65,13 @@ public class DocumentTest extends IntegrationTest {
GetEntityTypeEntityIdDocumentsResponse doc = ok(fineract().documents.getDocument("clients", clientId, documentId)); GetEntityTypeEntityIdDocumentsResponse doc = ok(fineract().documents.getDocument("clients", clientId, documentId));
assertThat(doc.getName()).isEqualTo("Test"); assertThat(doc.getName()).isEqualTo("Test");
assertThat(doc.getFileName()).isEqualTo(testFile.getName()); assertThat(doc.getFileName()).isEqualTo(testFile.getName());
assertThat(doc.getDescription()).isNull(); assertThat(doc.getDescription()).isEqualTo("The Description");
assertThat(doc.getId()).isEqualTo(documentId); assertThat(doc.getId()).isEqualTo(documentId);
assertThat(doc.getParentEntityType()).isEqualTo("clients"); assertThat(doc.getParentEntityType()).isEqualTo("clients");
assertThat(doc.getParentEntityId()).isEqualTo(clientId); assertThat(doc.getParentEntityId()).isEqualTo(clientId);
// TODO huh?! It's more than uploaded file; seems like a bug - it's including create body, not just file size // TODO FINERACT-1251 It's more than uploaded file; seems like a bug - it's including create body, not just file
assertThat(doc.getSize()).isEqualTo(testFile.length() + 411); // size
assertThat(doc.getSize()).isEqualTo(testFile.length() + 618);
assertThat(doc.getType()).isEqualTo("image/jpeg"); assertThat(doc.getType()).isEqualTo("image/jpeg");
// TODO doc.getStorageType() shouldn't be exposed by the API?! // TODO doc.getStorageType() shouldn't be exposed by the API?!
} }
@@ -82,7 +83,7 @@ public class DocumentTest extends IntegrationTest {
try (ResponseBody body = r.body()) { try (ResponseBody body = r.body()) {
assertThat(body.contentType()).isEqualTo(MediaType.get("image/jpeg")); assertThat(body.contentType()).isEqualTo(MediaType.get("image/jpeg"));
assertThat(body.bytes().length).isEqualTo(testFile.length()); assertThat(body.bytes().length).isEqualTo(testFile.length());
assertThat(body.contentLength()).isEqualTo(-1); // TODO testFile.length() assertThat(body.contentLength()).isEqualTo(testFile.length());
} }
assertThat(Parts.fileName(r)).hasValue(testFile.getName()); assertThat(Parts.fileName(r)).hasValue(testFile.getName());
} }
@@ -97,6 +98,9 @@ public class DocumentTest extends IntegrationTest {
GetEntityTypeEntityIdDocumentsResponse doc = ok(fineract().documents.getDocument("clients", clientId, documentId)); GetEntityTypeEntityIdDocumentsResponse doc = ok(fineract().documents.getDocument("clients", clientId, documentId));
assertThat(doc.getName()).isEqualTo(newName); assertThat(doc.getName()).isEqualTo(newName);
assertThat(doc.getDescription()).isEqualTo(newDescription); assertThat(doc.getDescription()).isEqualTo(newDescription);
// TODO FINERACT-1251 It's more than uploaded file; seems like a bug - it's including create body, not just file
// size
assertThat(doc.getSize()).isEqualTo(testFile.length() + 618);
} }
@Test @Test