You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by pt...@apache.org on 2020/11/06 03:27:29 UTC
[fineract] 04/04: Replace use of InputStream by ByteSource in
ImageData (FINERACT-1201)
This is an automated email from the ASF dual-hosted git repository.
ptuomola pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 140c55b7f2cdfd89d90e57eec426b65568b1166d
Author: Michael Vorburger <mi...@vorburger.ch>
AuthorDate: Sat Oct 31 18:56:24 2020 +0100
Replace use of InputStream by ByteSource in ImageData (FINERACT-1201)
---
.../documentmanagement/api/ImagesApiResource.java | 31 ++++++++++++++------
.../contentrepository/S3ContentRepository.java | 12 ++++++--
.../documentmanagement/data/ImageData.java | 25 ++++++----------
.../documentmanagement/data/ImageResizer.java | 33 ++++++++++++++--------
4 files changed, 61 insertions(+), 40 deletions(-)
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java
index 851af09..c745ff5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/api/ImagesApiResource.java
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.documentmanagement.api;
+import com.google.common.io.ByteSource;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart;
import com.sun.jersey.multipart.FormDataParam;
@@ -51,6 +52,8 @@ import org.apache.fineract.infrastructure.documentmanagement.service.ImageReadPl
import org.apache.fineract.infrastructure.documentmanagement.service.ImageWritePlatformService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
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.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -60,6 +63,8 @@ import org.springframework.stereotype.Component;
@Path("{entity}/{entityId}/images")
public class ImagesApiResource {
+ private static final Logger LOG = LoggerFactory.getLogger(ImagesApiResource.class);
+
private final PlatformSecurityContext context;
private final ImageReadPlatformService imageReadPlatformService;
private final ImageWritePlatformService imageWritePlatformService;
@@ -151,7 +156,7 @@ public class ImagesApiResource {
ImageData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight);
try {
- byte[] resizedImageBytes = resizedImage.getInputStream().readAllBytes();
+ byte[] resizedImageBytes = resizedImage.getByteSource().read();
final String clientImageAsBase64Text = imageDataURISuffix + Base64.getMimeEncoder().encodeToString(resizedImageBytes);
return Response.ok(clientImageAsBase64Text).build();
} catch (IOException e) {
@@ -174,14 +179,22 @@ public class ImagesApiResource {
final ImageData imageData = this.imageReadPlatformService.retrieveImage(entityName, entityId);
final ImageData resizedImage = imageResizer.resize(imageData, maxWidth, maxHeight);
- final ResponseBuilder response = Response.ok(resizedImage.getInputStream());
- final String dispositionType = "inline_octet".equals(output) ? "inline" : "attachment";
- response.header("Content-Disposition",
- dispositionType + "; filename=\"" + imageData.getEntityDisplayName() + ImageFileExtension.JPEG + "\"");
-
- // TODO: Need a better way of determining image type
-
- response.header("Content-Type", imageData.contentType());
+ ResponseBuilder response;
+ try {
+ 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();
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java
index ff34738..db1aae8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/contentrepository/S3ContentRepository.java
@@ -29,8 +29,10 @@ import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
+import com.google.common.io.ByteSource;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import org.apache.fineract.infrastructure.core.domain.Base64EncodedImage;
@@ -109,8 +111,14 @@ public class S3ContentRepository implements ContentRepository {
@Override
public ImageData fetchImage(final ImageData imageData) {
- final S3Object s3object = getObject(imageData.location());
- imageData.updateContent(s3object.getObjectContent());
+ imageData.updateContent(new ByteSource() {
+
+ @Override
+ public InputStream openStream() throws IOException {
+ final S3Object s3object = getObject(imageData.location());
+ return s3object.getObjectContent();
+ }
+ });
return imageData;
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java
index 3f7df51..9c15a77 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageData.java
@@ -18,27 +18,22 @@
*/
package org.apache.fineract.infrastructure.documentmanagement.data;
+import com.google.common.io.ByteSource;
+import com.google.common.io.Files;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
import org.apache.fineract.infrastructure.documentmanagement.domain.StorageType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class ImageData {
- private static final Logger LOG = LoggerFactory.getLogger(ImageData.class);
-
private final String location;
private final StorageType storageType;
private final String entityDisplayName;
private File file;
+ private ByteSource byteSource;
private ContentRepositoryUtils.ImageFileExtension fileExtension;
- private InputStream inputStream;
public ImageData(final String location, final StorageType storageType, final String entityDisplayName) {
this.location = location;
@@ -63,19 +58,15 @@ public class ImageData {
}
}
- public void updateContent(final InputStream objectContent) {
- this.inputStream = objectContent;
+ public void updateContent(final ByteSource byteSource) {
+ this.byteSource = byteSource;
}
- public InputStream getInputStream() {
+ public ByteSource getByteSource() {
if (this.file != null) {
- try {
- return new FileInputStream(this.file);
- } catch (FileNotFoundException e) {
- throw new IllegalStateException("FileNotFoundException: " + file, e);
- }
+ return Files.asByteSource(file);
}
- return this.inputStream;
+ return this.byteSource;
}
public String contentType() {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java
index 9241ea6..3653837 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/data/ImageResizer.java
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.infrastructure.documentmanagement.data;
+import com.google.common.io.ByteSource;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
@@ -26,6 +27,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Optional;
import javax.imageio.ImageIO;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils;
import org.apache.fineract.infrastructure.documentmanagement.contentrepository.ContentRepositoryUtils.ImageFileExtension;
@@ -42,26 +44,32 @@ public class ImageResizer {
if (maxWidth == null && maxHeight != null) {
return image;
}
- try (InputStream is = image.getInputStream()) {
- InputStream resizedIS = resizeImage(image.getFileExtension(), is, maxWidth != null ? maxWidth : Integer.MAX_VALUE,
+ try (InputStream is = image.getByteSource().openBufferedStream()) {
+ Optional<InputStream> optResizedIS = resizeImage(image.getFileExtension(), is, maxWidth != null ? maxWidth : Integer.MAX_VALUE,
maxHeight != null ? maxHeight : Integer.MAX_VALUE);
+ if (optResizedIS.isPresent()) {
+ ImageData resizedImage = new ImageData(image.location(), image.storageType(), image.getEntityDisplayName());
+ resizedImage.updateContent(new ByteSource() {
- ImageData resizedImage = new ImageData(image.location(), image.storageType(), image.getEntityDisplayName());
- resizedImage.updateContent(resizedIS);
- return resizedImage;
+ @Override
+ public InputStream openStream() throws IOException {
+ return optResizedIS.get();
+ }
+ });
+ return resizedImage;
+ }
+ return image;
} catch (IOException e) {
LOG.warn("resize() failed, returning original image: {}", e.getMessage(), e);
return image;
}
}
- private InputStream resizeImage(ImageFileExtension fileExtension, InputStream in, int maxWidth, int maxHeight) throws IOException {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
-
+ private Optional<InputStream> resizeImage(ImageFileExtension fileExtension, InputStream in, int maxWidth, int maxHeight)
+ throws IOException {
BufferedImage src = ImageIO.read(in);
if (src.getWidth() <= maxWidth && src.getHeight() <= maxHeight) {
- in.reset();
- return in;
+ return Optional.empty();
}
float widthRatio = (float) src.getWidth() / maxWidth;
float heightRatio = (float) src.getHeight() / maxHeight;
@@ -78,8 +86,9 @@ public class ImageResizer {
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(src, 0, 0, newWidth, newHeight, Color.BLACK, null);
g.dispose();
- ImageIO.write(target, fileExtension != null ? fileExtension.getValueWithoutDot() : "jpeg", os);
- return new ByteArrayInputStream(os.toByteArray());
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ ImageIO.write(target, fileExtension != null ? fileExtension.getValueWithoutDot() : "jpeg", os);
+ return Optional.of(new ByteArrayInputStream(os.toByteArray()));
}
}