diff --git a/src/main/java/de/deadlocker8/budgetmaster/images/Image.java b/src/main/java/de/deadlocker8/budgetmaster/images/Image.java index 973a25107a0d3d5047a905a020f41bc5a3211f56..6458e49fff365077d76f772925df7010e5b030d1 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/images/Image.java +++ b/src/main/java/de/deadlocker8/budgetmaster/images/Image.java @@ -2,10 +2,13 @@ package de.deadlocker8.budgetmaster.images; import com.google.gson.annotations.Expose; import de.deadlocker8.budgetmaster.accounts.Account; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.tomcat.util.codec.binary.Base64; import javax.persistence.*; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +import java.text.MessageFormat; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -18,16 +21,23 @@ public class Image private Integer ID; @NotNull - @Size(min = 1) @Expose - private String imagePath; + @Lob + private Byte[] image; + + @NotNull + @Expose + private String fileExtension; @OneToMany(mappedBy = "icon", fetch = FetchType.LAZY) private List<Account> referringAccounts; - public Image(String imagePath) + private static final String BASE_64_IMAGE_FORMAT = "data:image/{0};base64,{1}"; + + public Image(@NotNull Byte[] image, String fileExtension) { - this.imagePath = imagePath; + this.image = image; + this.fileExtension = fileExtension; } public Image() @@ -44,14 +54,30 @@ public class Image this.ID = ID; } - public String getImagePath() + public Byte[] getImage() + { + return image; + } + + public void setImage(Byte[] image) + { + this.image = image; + } + + public String getBase64EncodedImage() + { + final String encoded = Base64.encodeBase64String(ArrayUtils.toPrimitive(this.image)); + return MessageFormat.format(BASE_64_IMAGE_FORMAT, fileExtension, encoded); + } + + public String getFileExtension() { - return imagePath; + return fileExtension; } - public void setImagePath(String imagePath) + public void setFileExtension(String fileExtension) { - this.imagePath = imagePath; + this.fileExtension = fileExtension; } public List<Account> getReferringAccounts() @@ -64,7 +90,8 @@ public class Image { return "Image{" + "ID=" + ID + - ", imagePath='" + imagePath + '\'' + + ", image='" + image + '\'' + + ", fileExtension='" + fileExtension + '\'' + '}'; } @@ -73,13 +100,17 @@ public class Image { if(this == o) return true; if(o == null || getClass() != o.getClass()) return false; - Image image = (Image) o; - return Objects.equals(ID, image.ID) && Objects.equals(imagePath, image.imagePath); + Image other = (Image) o; + return Objects.equals(ID, other.ID) && + Arrays.equals(image, other.image) && + Objects.equals(fileExtension, other.fileExtension); } @Override public int hashCode() { - return Objects.hash(ID, imagePath); + int result = Objects.hash(ID, fileExtension); + result = 31 * result + Arrays.hashCode(image); + return result; } } \ No newline at end of file diff --git a/src/main/java/de/deadlocker8/budgetmaster/utils/Mappings.java b/src/main/java/de/deadlocker8/budgetmaster/utils/Mappings.java index ad3c5dd04b04a082b6a902b38958a26e1946cb88..d1b66d84bc29825740a7846ace6da5f455ba3a24 100644 --- a/src/main/java/de/deadlocker8/budgetmaster/utils/Mappings.java +++ b/src/main/java/de/deadlocker8/budgetmaster/utils/Mappings.java @@ -14,6 +14,7 @@ public final class Mappings public static final String ERROR = "/error"; public static final String FILTER = "/filter"; public static final String HOTKEYS = "/hotkeys"; + public static final String IMAGES = "/media"; public static final String LOGIN = "/login"; public static final String REPORTS = "/reports"; public static final String SEARCH = "/search"; diff --git a/src/main/resources/templates/accounts/accountFunctions.ftl b/src/main/resources/templates/accounts/accountFunctions.ftl index 99fabce75f6171c60a75e479dfa0bbc088be5866..a3ff14c09fcf337712a87ef3d3c5b01c40b03e97 100644 --- a/src/main/resources/templates/accounts/accountFunctions.ftl +++ b/src/main/resources/templates/accounts/accountFunctions.ftl @@ -19,7 +19,7 @@ <#macro accountIconOption image> <div class="col s4 m2 l2 account-icon-option-column"> <div class="account-icon-option"> - <img src="${image.getImagePath()}" class="account-icon-preview" alt="${image.getImagePath()}" data-image-id="${image.getID()}"/> + <img src="${image.getBase64EncodedImage()}" class="account-icon-preview" data-image-id="${image.getID()}"/> </div> </div> </#macro> \ No newline at end of file diff --git a/src/main/resources/templates/accounts/accounts.ftl b/src/main/resources/templates/accounts/accounts.ftl index f8256aeff4403135e6e09359eba23fcbf532a107..0f7d695ab17128bf940742915fe997ff4b9e64de 100644 --- a/src/main/resources/templates/accounts/accounts.ftl +++ b/src/main/resources/templates/accounts/accounts.ftl @@ -41,7 +41,7 @@ <a href="<@s.url '/accounts/${account.getID()?c}/toggleReadOnly'/>" class="btn-flat no-padding text-default tooltipped" data-position="right" data-tooltip="${toolTipText}">${lockIcon}</a> </#if> </td> - <td><#if account.getIcon()??><img src="${account.getIcon().getImagePath()}" class="account-icon"/></#if></td> + <td><#if account.getIcon()??><img src="${account.getIcon().getBase64EncodedImage()}" class="account-icon"/></#if></td> <td>${account.getName()}</td> <td> <a href="<@s.url '/accounts/${account.getID()?c}/edit'/>" class="btn-flat no-padding text-default"><i class="material-icons left">edit</i></a> diff --git a/src/main/resources/templates/accounts/newAccount.ftl b/src/main/resources/templates/accounts/newAccount.ftl index 83b2aa607d60c3737a93894cd4816b945471fc27..674668fd6555b26872b59c3767f4be9b43dcb1a4 100644 --- a/src/main/resources/templates/accounts/newAccount.ftl +++ b/src/main/resources/templates/accounts/newAccount.ftl @@ -54,7 +54,7 @@ <div id="account-icon" class="valign-wrapper"> <a href="#modalAccountIconSelect" id="account-icon-preview" class="modal-trigger"> - <img id="account-icon-preview-icon" src="<#if account.getIcon()??>${account.getIcon().getImagePath()}</#if>" class="account-icon-preview <#if account.getIcon()?? == false>hidden</#if>"/> + <img id="account-icon-preview-icon" src="<#if account.getIcon()??>${account.getIcon().getBase64EncodedImage()}</#if>" class="account-icon-preview <#if account.getIcon()?? == false>hidden</#if>"/> <div id="account-icon-placeholder" class="<#if account.getIcon()??>hidden</#if>">${locale.getString("account.new.icon.placeholder")}</div> </a> <@header.buttonFlat url='' icon='delete' id='button-remove-account-icon' localizationKey='' classes="no-padding text-default" noUrl=true/>