Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.genexus.CommonUtil;
import com.genexus.db.driver.*;
import com.genexus.common.interfaces.SpecificImplementation;
import com.genexus.db.driver.ResourceAccessControlList;

import java.util.Date;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.genexus.util;

public enum GxFileInfoSourceType {
Unknown,
LocalFile,
ExternalFile
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.genexus.db.driver;

import com.genexus.specific.java.Connect;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -15,6 +16,7 @@
import java.util.List;
import java.util.Random;

import com.genexus.db.driver.ResourceAccessControlList;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeTrue;

Expand All @@ -36,7 +38,7 @@ public boolean supportsObjectAcls() {

@Before
public void beforeEachTestMethod() {

Connect.init();
boolean testEnabled = false;
try {
testEnabled = ExternalProviderHelper.getEnvironmentVariable(getProviderName() + "_TEST_ENABLED", false).equals("true");
Expand Down
4 changes: 3 additions & 1 deletion gxoffice/src/main/java/com/genexus/gxoffice/Constants.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.genexus.gxoffice;

import com.genexus.db.driver.ResourceAccessControlList;

public class Constants {
public static boolean EXTERNAL_PRIVATE_UPLOAD = true;
public static ResourceAccessControlList EXTERNAL_UPLOAD_ACL = ResourceAccessControlList.Private;
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public short Save()
workBook.write(fs);
ByteArrayInputStream in = new ByteArrayInputStream(fs.toByteArray());
fs.close();
GXFile file = new GXFile(xlsFileName, Constants.EXTERNAL_PRIVATE_UPLOAD);
GXFile file = new GXFile(xlsFileName, Constants.EXTERNAL_UPLOAD_ACL);
file.create(in, true);
}
catch(Exception e)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.genexus.gxoffice.poi.sxssf;

import com.genexus.util.GxFileInfoSourceType;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.genexus.gxoffice.Constants;
import com.genexus.gxoffice.IExcelCells;
import com.genexus.gxoffice.IGxError;
import com.genexus.gxoffice.poi.xssf.StylesCache;
Expand All @@ -27,7 +29,7 @@ public short Open(String fileName) {
return errCod;
}
} else {
GXFile file = new GXFile(fileName);
GXFile file = new GXFile("", fileName, Constants.EXTERNAL_UPLOAD_ACL, GxFileInfoSourceType.Unknown);
if (file.exists()) {
// System.out.println("Opening..");
workBook = new SXSSFWorkbook(new XSSFWorkbook(file.getStream()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import com.genexus.util.GxFileInfoSourceType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
Expand Down Expand Up @@ -36,7 +37,7 @@ public short Open(String fileName) {
return errCod;
}
} else {
GXFile file = new GXFile(fileName, Constants.EXTERNAL_PRIVATE_UPLOAD);
GXFile file = new GXFile("", fileName, Constants.EXTERNAL_UPLOAD_ACL, GxFileInfoSourceType.Unknown);
if (file.exists()) {
// System.out.println("Opening..");
workBook = new XSSFWorkbook(file.getStream());
Expand Down Expand Up @@ -74,7 +75,8 @@ public short Save() {
workBook.write(fs);
ByteArrayInputStream in = new ByteArrayInputStream(fs.toByteArray());
fs.close();
GXFile file = new GXFile(xlsFileName, Constants.EXTERNAL_PRIVATE_UPLOAD);
boolean isAbsolute = new java.io.File(xlsFileName).isAbsolute();
GXFile file = new GXFile(xlsFileName, Constants.EXTERNAL_UPLOAD_ACL, isAbsolute);
file.create(in, true);
saved = true;
} catch (Exception e) {
Expand Down
148 changes: 99 additions & 49 deletions java/src/main/java/com/genexus/GxImageUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,99 +5,146 @@
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.*;

import com.genexus.db.driver.ResourceAccessControlList;
import com.genexus.util.GxFileInfoSourceType;
import com.genexus.util.GXFile;
import org.apache.logging.log4j.Logger;

public class GxImageUtil {
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(GxImageUtil.class);
private static int INVALID_CODE = -1;

private static String getImageAbsolutePath(String imageFile){
if (CommonUtil.isUploadPrefix(imageFile)) {
return new GXFile(imageFile).getAbsolutePath();
private static InputStream getInputStream(String filePathOrUrl) throws IOException {
return getGXFile(filePathOrUrl).getStream();
}

private static BufferedImage createBufferedImageFromURI(String filePathOrUrl) throws IOException
{
try (InputStream is = getGXFile(filePathOrUrl).getStream()) {
return ImageIO.read(is);
}
catch (IOException e) {
log.error("Failed to read image stream: " + filePathOrUrl);
throw e;
}
String defaultPath = com.genexus.ModelContext.getModelContext().getHttpContext().getDefaultPath();
return imageFile.startsWith(defaultPath)? imageFile : defaultPath + imageFile.replace("/", File.separator);
}

private static GXFile getGXFile(String filePathOrUrl) {
String basePath = (com.genexus.ModelContext.getModelContext() != null) ? com.genexus.ModelContext.getModelContext().getHttpContext().getDefaultPath(): "";
return new GXFile(basePath, filePathOrUrl, ResourceAccessControlList.Default, GxFileInfoSourceType.Unknown);
}

public static long getFileSize(String imageFile){
return new File(getImageAbsolutePath(imageFile)).length();
if (!isValidInput(imageFile))
return INVALID_CODE;

return new GXFile(imageFile).getLength();
}

public static int getImageHeight(String imageFile) {
if (!isValidInput(imageFile))
return INVALID_CODE;

try {
BufferedImage image = ImageIO.read(new File(getImageAbsolutePath(imageFile)));
return image.getHeight();
return createBufferedImageFromURI(imageFile).getHeight();
}
catch (IOException e) {
catch (Exception e) {
log.error("getImageHeight " + imageFile + " failed" , e);
return 0;
}
return INVALID_CODE;
}

private static boolean isValidInput(String imageFile) {
boolean isValid = imageFile != null && imageFile.length() > 0;
if (!isValid) {
log.debug("Image Api - FileName cannot be empty");
}
return isValid;
}

public static int getImageWidth(String imageFile) {
if (!isValidInput(imageFile))
return INVALID_CODE;

try {
BufferedImage image = ImageIO.read(new File(getImageAbsolutePath(imageFile)));
return image.getWidth();
return createBufferedImageFromURI(imageFile).getWidth();
}
catch (IOException e) {
catch (Exception e) {
log.error("getImageWidth " + imageFile + " failed" , e);
return 0;
}
return INVALID_CODE;
}

public static String crop(String imageFile, int x, int y, int width, int height){
public static String crop(String imageFile, int x, int y, int width, int height) {
if (!isValidInput(imageFile))
return "";

try {
String absolutePath = getImageAbsolutePath(imageFile);
BufferedImage image = ImageIO.read(new File(absolutePath));
BufferedImage cropedImage = image.getSubimage(x, y, width, height);
ImageIO.write(cropedImage, CommonUtil.getFileType(absolutePath), new FileOutputStream(absolutePath));
BufferedImage image = createBufferedImageFromURI(imageFile);
BufferedImage croppedImage = image.getSubimage(x, y, width, height);
writeImage(croppedImage, imageFile);
}
catch (IOException e) {
catch (Exception e) {
log.error("crop " + imageFile + " failed" , e);
}
return imageFile;
}

public static String flipHorizontally(String imageFile){
private static void writeImage(BufferedImage croppedImage, String destinationFilePathOrUrl) throws IOException {
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
ImageIO.write(croppedImage, CommonUtil.getFileType(destinationFilePathOrUrl), outStream);
try (ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray())) {
GXFile file = getGXFile(destinationFilePathOrUrl);
file.create(inStream, true);
file.close();
}
}
}

public static String flipHorizontally(String imageFile) {
if (!isValidInput(imageFile))
return "";

try {
String absolutePath = getImageAbsolutePath(imageFile);
BufferedImage image = ImageIO.read(new File(absolutePath));
BufferedImage image = createBufferedImageFromURI(imageFile);
AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-image.getWidth(null), 0);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage flipedImage = op.filter(image, null);
ImageIO.write(flipedImage, CommonUtil.getFileType(absolutePath), new FileOutputStream(absolutePath));
BufferedImage flippedImage = op.filter(image, null);
writeImage(flippedImage, imageFile);
}
catch (IOException e) {
catch (Exception e) {
log.error("flip horizontal " + imageFile + " failed" , e);
}
return imageFile;
}

public static String flipVertically(String imageFile){
public static String flipVertically(String imageFile) {
if (!isValidInput(imageFile))
return "";

try {
String absolutePath = getImageAbsolutePath(imageFile);
BufferedImage image = ImageIO.read(new File(absolutePath));
BufferedImage image = createBufferedImageFromURI(imageFile);
AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
tx.translate(0, -image.getHeight(null));
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage flipedImage = op.filter(image, null);
ImageIO.write(flipedImage, CommonUtil.getFileType(absolutePath), new FileOutputStream(absolutePath));
BufferedImage flippedImage = op.filter(image, null);
writeImage(flippedImage, imageFile);
}
catch (IOException e) {
catch (Exception e) {
log.error("flip vertical " + imageFile + " failed" , e);
}
return imageFile;
}

public static String resize(String imageFile, int width, int height, boolean keepAspectRatio){
public static String resize(String imageFile, int width, int height, boolean keepAspectRatio) {
if (!isValidInput(imageFile))
return "";

try {
String absolutePath = getImageAbsolutePath(imageFile);
BufferedImage image = ImageIO.read(new File(absolutePath));
BufferedImage image = createBufferedImageFromURI(imageFile);
if (keepAspectRatio) {
double imageHeight = image.getHeight();
double imageWidth = image.getWidth();
Expand All @@ -112,34 +159,37 @@ public static String resize(String imageFile, int width, int height, boolean kee
Graphics2D g2d = resizedImage.createGraphics();
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
ImageIO.write(resizedImage, CommonUtil.getFileType(absolutePath), new FileOutputStream(absolutePath));
writeImage(resizedImage, imageFile);
}
catch (IOException e) {
catch (Exception e) {
log.error("resize " + imageFile + " failed" , e);
}
return imageFile;
}

public static String scale(String imageFile, short percent){
public static String scale(String imageFile, short percent) {
if (!isValidInput(imageFile))
return "";

try {
String absolutePath = getImageAbsolutePath(imageFile);
BufferedImage image = ImageIO.read(new File(absolutePath));
BufferedImage image = createBufferedImageFromURI(imageFile);
imageFile = resize(imageFile, image.getWidth() * percent / 100, image.getHeight() * percent / 100,true);
}
catch (IOException e) {
catch (Exception e) {
log.error("scale " + imageFile + " failed" , e);
}
return imageFile;
}

public static String rotate(String imageFile, short angle){
public static String rotate(String imageFile, short angle) {
if (!isValidInput(imageFile))
return "";
try {
String absolutePath = getImageAbsolutePath(imageFile);
BufferedImage image = ImageIO.read(new File(absolutePath));
BufferedImage image = createBufferedImageFromURI(imageFile);
BufferedImage rotatedImage = rotateImage(image, angle);
ImageIO.write(rotatedImage, CommonUtil.getFileType(absolutePath), new FileOutputStream(absolutePath));
writeImage(rotatedImage, imageFile);
}
catch (IOException e) {
catch (Exception e) {
log.error("rotate " + imageFile + " failed" , e);
}
return imageFile;
Expand Down
16 changes: 16 additions & 0 deletions java/src/main/java/com/genexus/PrivateUtilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.InvalidPathException;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.Random;
import java.util.zip.DeflaterOutputStream;
Expand Down Expand Up @@ -608,6 +610,20 @@ private static File parent(File f) {
return new File(dirname);
}

/**
* <pre>
* Checks if a string is an absolute path to local file system.
* Null safe.
* </pre>
*/
public static boolean isAbsoluteFilePath(String path) {
try {
return Paths.get(path).isAbsolute();
} catch (InvalidPathException | NullPointerException ex) {
return false;
}
}

public static String addLastPathSeparator(String dir)
{
return addLastChar(dir, File.separator);
Expand Down
1 change: 1 addition & 0 deletions java/src/main/java/com/genexus/db/driver/GXResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.genexus.internet.HttpContext;
import com.genexus.util.GXFile;
import com.genexus.util.GXServices;
import com.genexus.db.driver.ResourceAccessControlList;

public final class GXResultSet implements ResultSet, com.genexus.db.IFieldGetter, IGXResultSet
{
Expand Down
5 changes: 3 additions & 2 deletions java/src/main/java/com/genexus/specific/java/FileUtils.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.genexus.specific.java;

import com.genexus.common.classes.AbstractGXFile;
import com.genexus.util.GXFile;
import com.genexus.db.driver.ResourceAccessControlList;
import com.genexus.util.GXFile;
import com.genexus.util.GxFileInfoSourceType;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -47,7 +48,7 @@ public void copyFile(File file, File file2) throws IOException {

@Override
public AbstractGXFile createFile(String file, ResourceAccessControlList acl, boolean local) {
return new GXFile(file, acl, local);
return new GXFile(file, acl, local ? GxFileInfoSourceType.LocalFile: GxFileInfoSourceType.Unknown);
}

}
Loading