| /** |
| * |
| * Copyright (c) 2011, 2017 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| * Jose Dominguez (Compex Systemhaus GmbH) - ongoing development |
| */ |
| package org.eclipse.osbp.blob.service; |
| |
| import java.awt.Image; |
| import java.awt.image.BufferedImage; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.sql.Blob; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.imageio.ImageIO; |
| import javax.xml.bind.DatatypeConverter; |
| |
| import org.apache.commons.compress.utils.IOUtils; |
| import org.eclipse.osbp.blob.component.BlobEvent; |
| import org.eclipse.osbp.blob.component.BlobUploadComponent; |
| import org.eclipse.osbp.blob.dtos.BlobDto; |
| import org.eclipse.osbp.blob.dtos.BlobMappingDto; |
| import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess; |
| import org.eclipse.osbp.jpa.services.Query; |
| import org.eclipse.osbp.jpa.services.filters.LAnd; |
| import org.eclipse.osbp.jpa.services.filters.LCompare; |
| import org.eclipse.osbp.runtime.common.filter.IDTOService; |
| import org.eclipse.osbp.runtime.common.filter.IQuery; |
| import org.eclipse.osbp.ui.api.customfields.IBlobEvent; |
| import org.eclipse.osbp.ui.api.customfields.IBlobService; |
| import org.eclipse.osbp.ui.api.customfields.IBlobTyping; |
| import org.eclipse.osbp.ui.api.customfields.IBlobUploadEventListener; |
| import org.osgi.service.component.annotations.Component; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.server.StreamResource; |
| import com.vaadin.server.StreamResource.StreamSource; |
| import com.vaadin.shared.ui.label.ContentMode; |
| import com.vaadin.ui.Label; |
| |
| /** |
| * Provides and persist blob data from and into a database via JPA. For images |
| * different sizes are calculated and stored that can be retrieved later to get |
| * better performance |
| * |
| * @author dominguez |
| * |
| */ |
| @Component |
| public class BlobService implements IBlobService { |
| private IDTOService<BlobMappingDto> dtoBlobMappingDtoService; |
| private Logger log = LoggerFactory.getLogger(BlobService.class); |
| private List<IBlobUploadEventListener> listeners = new ArrayList<>(); |
| private BlobTypingAPI blobAPI; |
| |
| private static final String DEFAULT_EXCEL_ICON = "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"; |
| private static final String DEFAULT_WORD_ICON = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFT0lEQVR4XrVXa2wUVRg9Mzv7brftVra1UEBAoIAWKsaCyMOiEqKoCVrDHxORhKg/sFGh/kETLSn+ITbRX0pEiaGQ+CAxCKlWJaiFEjEGFSoYhT720W132+7O497rN7PLpkuGsBvLSU7ud2d2cs539rv7kIQQMCFJEq5hx44d79fW1m5HgRBEiLwr1nY4lsCmTRufW7Gi8QDpMFyHlpYWKLABmdlON/NFhMgJUUX7vDp3n9bcvu2tNvT0nO3Yt+/dCQCHYAMZ9vi/4hZNLFh4p39iIv1xW9uep2EDZff+wXcMnbGWjr9hGAy6YUAd7UVn1xAYZ+CcgzFBNc9RCAc8jnHMq5Zw79L5tuJZfUyfUYNgsMJ54vg3n+zZ0y5aW3cezjPQWFfyynA8Dk0XUE1qgBqqx4XLYdpz2jOigTStup4xKBw+TIzHUVfZj+VkwEY8l4Db6UZwegWaHlrr7DrRfZBMYLIJxRSfFdIwpzZoCUiSoCS41bksA+DCMudwCEgAkeP0+Qg+/DIKNWDcUFzkxlOiZxVUV1VhzYOrnd1d3Qfb2/eKnTtfO2IZMEWrKsvg9QSIZgIclUEFfo+MeMIA5wJer4KJFKOakQCHz6eCGxqAG4vTaj27f/9H5lBb+yycVH/a3Nz8a2dnZ5+ikoFTv0SRMlLQDIbByDjWNgRQXurD1z9HMZJIY/P6Gpz4MYL4mIqhcBRQY/C6ZeDG4hZf3bUrYyQvJWBv226FxOOmGVkn0TtqvPB5JJzrS6K8BCjxyCQeQe/FEbo2CocEDMWSOH1hFLHYCJbWBaHqBrjg9uIWYSc+OYkQ0a2YwzV/dgn8ASeO/tCPitIy/BthOHcpQbHrcDmB3/6M4EosjfDgAF7fMhOLFs3E599dBOcoVnyygQDRab0FGlGCC5IE9P6ehMoTiCdVy3E6NY7DXQkMJAUWVKWxYe0i9P4RIXEDgjuKFhfIwU2UFU3LDJrBMkb+iWpIqQzgAJc40rpG5EhGB9G8rR6Vt1UgrV6xTgkJFCturZOhqJqA4AKcSTDTiCV1VHg5KgPA1ViKhHQ6ASksni6wbtUSJMd06/UpXcelfgOfdfejGDQtD+Yb0HQj5zpN9WhiDA/XV8KlMPRdjUCnaxPxq3h2axP8Pj+sxASHInHMrvbi8dXVhXZOtEnAHEIBAZ1xDITjqC4T2Nw0E8dO9iE2PIxEcgzrlpTivnsWUvQMEjKJpbVMAl98P4hisK6hPG9vDSHjAtVBF55aE8Jdc8sxb87tmH05jA0NQeiaB888sQIet8eaEYcsgfQhSwKzqrx4bFVVoZ1niTwoOnXCdB11C/x486WV0A2OVJrj0fVL8eQjy6wHUhqDqhqWuCLLkMEpDQ2XB4CjJ4dQDNYsK8s3wB1enDkfxmAcNGwqTN9McAgmwDknZlfzGjc75zh3YQhObylmTBPYuDJUcOcCNglEY9Hh946EZV07Y0XJmQFJaOUutyvzdcwYmElugHNaDQNw+uFycFwZGsdXp8IoBg/UB/INXOw5dMhg3MU4AZwEOebV+LY1LF4OLiQIIRMVEndmO+Gg18MlCyycOxcbGqcV2rn9DPzVc+CF638Tbln/8rY3Wp+HAG56zo/9FEExuP/u0nwDsEeumyLPuX3n+ftCDOQitM75VGLlktJiDMA851PXeaYu1EDxsX97dgQ3Q+PikoITKLpz+pCx7zxXF/6/YMpjFyLXWEEGbqV4gQZuvbhK5LYzYBjGB+1v796KW4RIJHIcQIKo2xro6Oh4EUArMUQMEN2YOqhZ8bBZK7CHnnWoEp1EGVMHTtSzRvT/AHfRlTXQaR7HAAAAAElFTkSuQmCC"; |
| private static final String DEFAULT_PDF_ICON = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94LGQw5BlDcLxAAABArSURBVFgJASAQ3+8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKioqAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATR0dFO+/v7BAMDAxwCAgIp/////f///xP9/f0WAAAA//j4+Ar+/v7bPj4+XgAAAP4AAAD/AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAALq6ujgMDAw8BgYGKP39/f0FBQUwAQEBFQAAAAH///8f////AQEBAQD4+PgAAQEBAAEBAQAAAAAAAwMDAAICAgAEBAQAAQEBAAUFBQAFBQUABgYGAAoKCgDX19fr3d3dbGBgYK0AAAD9AAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAM/Pz/8hISEA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wACAgIA4ODgADAwMAEAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAICAgAKCgoA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAgICAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAAAAAAAAAEAAAD/AAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAD+AAAA/wAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAABwcAAAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAACAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD//v4A//7+AP/+/gD//v4A//7+AP8HBwD/d3cA/7W1AP8DAwD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAYAAAACAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAEAAAAAAAAAAAAAAAEBAQABAQEAAAEBAAD6+gD9vLwA/xkZAAEAAAABAQEAAAAAAAAAAAABAQEAAQEBAAAAAAAAAAAAAQEBAAEBAQAAAAAAAQEBAAAAAAUAAAACAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAP///wAAAAAA/v7+AAAAAAAA//8AAAAAAP///wAAAAAAAAEBAAEGBgD7/PwABysrAP78/AAA//8AAAAAAAAAAAD///8AAAAAAAAAAAAAAAAA////AAAAAAACAgIAAAAAAAAAAAQAAAACAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8DAwD9FRUA/L+/AAEEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAQAAAABAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQAAAQEAAAAAAAH+/gD/JycA+9bWAAABAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAD5+QADQUEA/u7uAP/9/QD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0CAgIB/v7+AAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8FBQD50NAA8ZOTAAAFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A/v7+AJGRkUv+/v4AAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP7w8AD1y8sABUZGAO6GhgAABAQA////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAEBAQgAAAAFAAAAAQAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQMDAOlzcwARfn4AFY6OAPXIyAD3y8sAAQUFAAECAgABAwMAAQMDAAEDAwAAAQEAAAAAAAAAAAAAAAAA////ACsrKz0AAAABAAAAAQAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAA+uTkAP4KCgAIODgA/PT0ABqlpQDmbm4ABLe3AA9SUgD409MA//z8AAINDQAOR0cAAAMDAAAAAAAAAAAAAAAAAAICAgwAAAAEAAAAAQAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBwcA8K+vABBeXgD53t4A9tDQAOucnAAAFBQA+efnANtNTQD11NQABBwcAAIJCQDrlpYAAggIAAEAAAAAAAAAAAAAAAQEBBQAAAACAAAAAQAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAADAwD54uIA6aSkAAgxMQADDw8ABBUVABNeXgACCwsAAAEBABru7gD319cA88rKAPrn5wAPPj4A+ujoAAQQEAABAAAAAAAAAP7+/ggAAAABAAAAAQAAAAAEAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AAAAAAAAAQEA/fX1APzv7wDbaGgAKbq6AAQPDwD//PwAAP//AAAAAAD//PwAAAAAAAINDQAMNzcADT09AAADAwD//PwA//v7AP///wAAAAAAAAAA//z8/AQAAAACAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAAAAAAAAAD87+8A6qysAPPS0gAXY2MABA4OAP/7+wAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A/vn5AP729gD/+voAAP//AAAAAAAAAAAAAAAAAQgICBBHR0cUAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAP///wD///8A/wAAAAACAgDXdnYADDU1AOKdnQATTEwA/vv7AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAQEBAUICAgJAAAAAwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAPno6AD9AgIA4qKiAC6jowACBQUAAAAAAAAAAAABAQEAAAAAAAEBAQABAQEAAAAAAAAAAAABAQEAAQEBAAAAAAAAAAAAAQEBAAEBAQAAAAAAAAAAAAcHBwsYGBgRAAAAAwAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AAYWFgAxoKAAAP//AP339wD+/v4AAAAAAAAAAAD///8AAAAAAP///wAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAA////AAAAAAABAQEA////AAcHBwMBAQEFAAAAAwAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/+/gD99vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAAAAAAcHBwUHBwcKAAAAAQAAAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAAA/wICAgACAgIEAAAAAgAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAACAgIA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEABAQEAXh4eFfT09PbAAAA+wAAAP8BAAAAAAAAAAAAAAAAAAAAAMfHx9n6+vr1/Pz8Bf39/QIAAAAAAAAAAAEBAQAAAAD/AAAAAAEBAf8AAAAAAQEB/wEBAf8AAAAAAQEB/wAAAAAAAAAAAAAAAAAAAAABAQH/AAAAAAAAAAAAAAD/BQUFDTs7OzIAAAADAAAA9QAAAPsAAAAAAAAAAAAAAAAAyMjIAAAAAAAAAAACAAAAEQAAABgAAAAZAAAAGAAAABYAAAAVAAAAFAAAABEAAAAPAAAADQAAAAsAAAAHAAAABQAAAAYAAAAGAAAABQAAAAQAAAADAAAAAwAAAAIAAAAAAAAAABUVFQMAAAABAAAAAAAAAACyU1AG+CMCBAAAAABJRU5ErkJggg=="; |
| private static final String DEFAULT_IMAGE = "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"; |
| |
| private static final String DEFAULTBLOBFILENAME = "osbee.png"; |
| private static final String DEFAULTBLOBMIMETYPE = "image/png"; |
| |
| private static final Map<String,String> mimeTypes = createMap(); |
| |
| private static Map<String,String> createMap() { |
| Map<String,String> myMap = new HashMap<>(); |
| |
| // we store the file extension as a key and the mimetype as value |
| myMap.put("3dm","x-world/x-3dmf"); |
| myMap.put("3dmf","x-world/x-3dmf"); |
| myMap.put("ai","application/postscript"); |
| myMap.put("aif","audio/x-aiff"); |
| myMap.put("aifc","audio/x-aiff"); |
| myMap.put("aiff","audio/x-aiff"); |
| myMap.put("asd","application/astound"); |
| myMap.put("asn","application/astound"); |
| myMap.put("au","audio/basic"); |
| myMap.put("avi","video/x-msvideo"); |
| myMap.put("bcpio","application/x-bcpio"); |
| myMap.put("bin","application/octet-stream"); |
| myMap.put("bmp","image/bmp"); |
| myMap.put("cab","application/x-shockwave-flash"); |
| myMap.put("cdf","application/x-netcdf"); |
| myMap.put("chm","application/mshelp"); |
| myMap.put("cht","audio/x-dspeeh"); |
| myMap.put("class","application/octet-stream"); |
| myMap.put("cod","image/cis-cod"); |
| myMap.put("com","application/octet-stream"); |
| myMap.put("cpio","application/x-cpio"); |
| myMap.put("csh","application/x-csh"); |
| myMap.put("css","text/css"); |
| myMap.put("csv","text/comma-separated-values"); |
| myMap.put("dcr","application/x-director"); |
| myMap.put("dir","application/x-director"); |
| myMap.put("doc","application/msword"); |
| myMap.put("docx","application/vnd.openxmlformats-officedocument. wordprocessingml.document"); |
| myMap.put("dot","application/msword"); |
| myMap.put("dus","audio/x-dspeeh"); |
| myMap.put("dvi","application/x-dvi"); |
| myMap.put("dwf","drawing/x-dwf"); |
| myMap.put("dwg","application/acad"); |
| myMap.put("dxf","application/dxf"); |
| myMap.put("dxr","application/x-director"); |
| myMap.put("eps","application/postscript"); |
| myMap.put("es","audio/echospeech"); |
| myMap.put("etx","text/x-setext"); |
| myMap.put("evy","application/x-envoy"); |
| myMap.put("exe","application/octet-stream"); |
| myMap.put("fh4","image/x-freehand"); |
| myMap.put("fh5","image/x-freehand"); |
| myMap.put("fhc","image/x-freehand"); |
| myMap.put("fif","image/fif"); |
| myMap.put("file","application/octet-stream"); |
| myMap.put("gif","image/gif"); |
| myMap.put("gtar","application/x-gtar"); |
| myMap.put("gz","application/gzip"); |
| myMap.put("hdf","application/x-hdf"); |
| myMap.put("hlp","application/mshelp"); |
| myMap.put("hqx","application/mac-binhex40"); |
| myMap.put("htm","text/html"); |
| myMap.put("html","text/html"); |
| myMap.put("ico","image/x-icon"); |
| myMap.put("ief","image/ief"); |
| myMap.put("ini","application/octet-stream"); |
| myMap.put("jpe","image/jpeg"); |
| myMap.put("jpeg","image/jpeg"); |
| myMap.put("jpg","image/jpeg"); |
| myMap.put("js","application/javascript"); |
| myMap.put("json","application/json"); |
| myMap.put("latex","application/x-latex"); |
| myMap.put("man","application/x-troff-man"); |
| myMap.put("mbd","application/mbedlet"); |
| myMap.put("mcf","image/vasa"); |
| myMap.put("me","application/x-troff-ms"); |
| myMap.put("mid","audio/x-midi"); |
| myMap.put("midi","audio/x-midi"); |
| myMap.put("mif","application/mif"); |
| myMap.put("mov","video/quicktime"); |
| myMap.put("movie","video/x-sgi-movie"); |
| myMap.put("mp2","audio/x-mpeg"); |
| myMap.put("mp3","audio/mpeg"); |
| myMap.put("mp4","video/mp4"); |
| myMap.put("mpe","video/mpeg"); |
| myMap.put("mpeg","video/mpeg"); |
| myMap.put("mpg","video/mpeg"); |
| myMap.put("nc","application/x-netcdf"); |
| myMap.put("nsc","application/x-nschat"); |
| myMap.put("oda","application/oda"); |
| myMap.put("ogg","video/ogg"); |
| myMap.put("ogv","video/ogg"); |
| myMap.put("pbm","image/x-portable-bitmap"); |
| myMap.put("pdf","application/pdf"); |
| myMap.put("pgm","image/x-portable-graymap"); |
| myMap.put("php","application/x-httpd-php"); |
| myMap.put("phtml","application/x-httpd-php"); |
| myMap.put("png","image/png"); |
| myMap.put("pnm","image/x-portable-anymap"); |
| myMap.put("pot","application/mspowerpoint"); |
| myMap.put("ppm","image/x-portable-pixmap"); |
| myMap.put("pps","application/mspowerpoint"); |
| myMap.put("ppt","application/mspowerpoint"); |
| myMap.put("ppz","application/mspowerpoint"); |
| myMap.put("ps","application/postscript"); |
| myMap.put("ptlk","application/listenup"); |
| myMap.put("qd3","x-world/x-3dmf"); |
| myMap.put("qd3d","x-world/x-3dmf"); |
| myMap.put("qt","video/quicktime"); |
| myMap.put("ra","audio/x-pn-realaudio"); |
| myMap.put("ram","audio/x-pn-realaudio"); |
| myMap.put("ras","image/cmu-raster"); |
| myMap.put("reg","application/force-download"); |
| myMap.put("rgb","image/x-rgb"); |
| myMap.put("roff","application/x-troff"); |
| myMap.put("rpm","audio/x-pn-realaudio-plugin"); |
| myMap.put("rtc","application/rtc"); |
| myMap.put("rtf","text/rtf"); |
| myMap.put("rtx","text/richtext"); |
| myMap.put("sca","application/x-supercard"); |
| myMap.put("sgm","text/x-sgml"); |
| myMap.put("sgml","text/x-sgml"); |
| myMap.put("sh","application/x-sh"); |
| myMap.put("shar","application/x-shar"); |
| myMap.put("shtml","text/html"); |
| myMap.put("sit","application/x-stuffit"); |
| myMap.put("smp","application/studiom"); |
| myMap.put("snd","audio/basic"); |
| myMap.put("spc","text/x-speech"); |
| myMap.put("spl","application/futuresplash"); |
| myMap.put("spr","application/x-sprite"); |
| myMap.put("sprite","application/x-sprite"); |
| myMap.put("src","application/x-wais-source"); |
| myMap.put("stream","audio/x-qt-stream"); |
| myMap.put("sv4cpio","application/x-sv4cpio"); |
| myMap.put("sv4crc","application/x-sv4crc"); |
| myMap.put("svg","image/svg+xml"); |
| myMap.put("swf","application/x-shockwave-flash"); |
| myMap.put("t","application/x-troff"); |
| myMap.put("talk","text/x-speech"); |
| myMap.put("tar","application/x-tar"); |
| myMap.put("tbk","application/toolbook"); |
| myMap.put("tcl","application/x-tcl"); |
| myMap.put("tex","application/x-tex"); |
| myMap.put("texi","application/x-texinfo"); |
| myMap.put("texinfo","application/x-texinfo"); |
| myMap.put("tif","image/tiff"); |
| myMap.put("tiff","image/tiff"); |
| myMap.put("tr","application/x-troff"); |
| myMap.put("troff","application/x-troff-me"); |
| myMap.put("tsi","audio/tsplayer"); |
| myMap.put("tsp","application/dsptype"); |
| myMap.put("tsv","text/tab-separated-values"); |
| myMap.put("txt","text/plain"); |
| myMap.put("ustar","application/x-ustar"); |
| myMap.put("viv","video/vnd.vivo"); |
| myMap.put("vivo","video/vnd.vivo"); |
| myMap.put("vmd","application/vocaltec-media-desc"); |
| myMap.put("vmf","application/vocaltec-media-file"); |
| myMap.put("vox","audio/voxware"); |
| myMap.put("vts","workbook/formulaone"); |
| myMap.put("vtts","workbook/formulaone"); |
| myMap.put("wav","audio/wav"); |
| myMap.put("wbmp","image/vnd.wap.wbmp"); |
| myMap.put("webm","video/webm"); |
| myMap.put("wml","text/vnd.wap.wml"); |
| myMap.put("wmlc","application/vnd.wap.wmlc"); |
| myMap.put("wmls","text/vnd.wap.wmlscript"); |
| myMap.put("wmlsc","application/vnd.wap.wmlscriptc"); |
| myMap.put("wrl","x-world/x-vrml"); |
| myMap.put("xbm","image/x-xbitmap"); |
| myMap.put("xhtml","application/xhtml+xml"); |
| myMap.put("xla","application/msexcel"); |
| myMap.put("xls","application/msexcel"); |
| myMap.put("xlsx","application/vnd.openxmlformats-officedocument. spreadsheetml.sheet"); |
| myMap.put("xml","text/xml"); |
| myMap.put("xpm","image/x-xpixmap"); |
| myMap.put("xwd","image/x-windowdump"); |
| myMap.put("z","application/x-compress"); |
| myMap.put("zip","application/zip"); |
| return myMap; |
| } |
| |
| private static String getMimetype ( String ext ) { |
| ext = ext.toLowerCase(); |
| return mimeTypes.containsKey(ext)?mimeTypes.get(ext):mimeTypes.get("file"); |
| } |
| |
| |
| |
| /** |
| * Inner class that extract the width and height values from the specified |
| * resolution string and provides them. |
| * |
| * @author dominguez |
| * |
| */ |
| class ImageBlobResolution { |
| int width; |
| int height; |
| |
| public ImageBlobResolution(String normResolution) { |
| super(); |
| this.width = 0; |
| this.height = 0; |
| String[] resArr = normResolution.split("x"); |
| if (resArr.length == 2) { |
| try { |
| this.width = Integer.parseInt(resArr[0]); |
| this.height = Integer.parseInt(resArr[1]); |
| } catch (NumberFormatException e) { |
| log.error(e.getLocalizedMessage()); |
| } |
| } |
| } |
| |
| } |
| |
| // ***************** Constructor ************ |
| |
| public BlobService() { |
| if (DtoServiceAccess.getService(BlobMappingDto.class) instanceof IDTOService<?>) { |
| dtoBlobMappingDtoService = DtoServiceAccess.getService(BlobMappingDto.class); |
| } |
| this.blobAPI = new BlobTypingAPI(); |
| } |
| |
| @Override |
| public void addBlobUploadListener(IBlobUploadEventListener listener) { |
| listeners.add(listener); |
| } |
| |
| @Override |
| public void removeBlobUploadListener(IBlobUploadEventListener listener) { |
| listeners.remove(listener); |
| } |
| |
| protected synchronized void notifyBlobUploadEvent(IBlobEvent event) { |
| for (IBlobUploadEventListener listener : listeners) { |
| listener.blobUploaded(event); |
| } |
| } |
| |
| /** |
| * Encodes the byte array representation of the blob into a base64 string |
| * representation. |
| * |
| * @param data |
| * @return base64 encoded string |
| */ |
| private String encodeBase64(byte[] data) { |
| return DatatypeConverter.printBase64Binary(data); |
| } |
| |
| /** |
| * Decodes the base 64String into a byte array |
| * |
| * @param data |
| * @return base64 encoded string |
| */ |
| private byte[] decodeBase64(byte[] data) { |
| return DatatypeConverter.parseBase64Binary(new String(data)); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ui.api.customfields.IBlobService#createBlobMappingBlobs( |
| * java.io.InputStream, int) |
| */ |
| @Override |
| public List<Object> createBlobMappingBlobs(InputStream stream, int mimeType) throws IOException { |
| return createBlobMappingBlobs(stream, blobAPI.getMimeTypeContentTypeById(mimeType)); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ui.api.customfields.IBlobService#createBlobMappingBlobs( |
| * java.io.InputStream, java.lang.String) |
| */ |
| @Override |
| public List<Object> createBlobMappingBlobs(InputStream stream, String mimeType) throws IOException { |
| List<Object> blobList = null; |
| byte[] bytes = IOUtils.toByteArray(stream); |
| // In case of a image blob |
| if (isImage(mimeType)) { |
| blobList = createImages(bytes, blobAPI, mimeType); |
| } else { |
| // Otherwise |
| blobList = createBlobList(bytes); |
| } |
| return blobList; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ui.api.customfields.IBlobService#createBlobMapping(java. |
| * io.InputStream, java.lang.String, java.lang.String) |
| */ |
| @Override |
| public String createBlobMapping(InputStream stream, String fileName, String mimeType) { |
| BlobMappingDto blobMapping = new BlobMappingDto(); |
| blobMapping.setFileName(fileName); |
| if ( mimeType == null || mimeType.isEmpty() ) { |
| int i = fileName.lastIndexOf('.'); |
| mimeType = getMimetype(i>0?fileName.substring(i+1):"file"); |
| } |
| blobMapping.setMimeTypeId(blobAPI.getMimeTypeContentTypeId(mimeType)); |
| try { |
| List<Object> blobList = createBlobMappingBlobs(stream, mimeType); |
| for (Object obj : blobList) { |
| blobMapping.addToBlobsRef((BlobDto) obj); |
| } |
| dtoBlobMappingDtoService.update(blobMapping); |
| IBlobEvent event = new BlobEvent(this, true, blobMapping.getId(), "", fileName); |
| notifyBlobUploadEvent(event); |
| return blobMapping.getId(); |
| } catch (IOException e) { |
| log.error(e.getLocalizedMessage()); |
| return null; |
| } |
| } |
| |
| /** |
| * Creates for the specified image blob data by {@code byte[]} the base64 |
| * encoded image representation and a resized copy for each of the |
| * predefined resolutions and send them back as a blob list ({@code List< |
| * |
| * @link Blob}>}). |
| * |
| * @param bytes |
| * @param blobAPI |
| * @param mimeType |
| * @throws IOException |
| * |
| */ |
| private List<Object> createImages(byte[] bytes, BlobTypingAPI blobAPI, String mimeType) throws IOException { |
| List<Object> blobList = new ArrayList<>(); |
| for (int i = 0; i < blobAPI.getNormalizer().size(); i++) { |
| ImageBlobResolution imgBlobRes = new ImageBlobResolution(blobAPI.getNormalizerResolutionByListIndex(i)); |
| // In case of resolution '0' no scaling will be done in 'getImage' |
| BufferedImage img = getImage(bytes, imgBlobRes.width, imgBlobRes.height); |
| byte[] imageBytes = imageToByteArray(img, mimeType); |
| blobList.add(createImageBlob(imageBytes, blobAPI.getNormalizerResolutionIdByListIndex(i))); |
| } |
| return blobList; |
| } |
| |
| /** |
| * Converts a {@link BufferedImage} into a byte array of a image. |
| * |
| * @param image |
| * @param mimeType |
| * @return a converted {@link BufferedImage} to a byte array. |
| * @throws IOException |
| */ |
| private byte[] imageToByteArray(BufferedImage image, String mimeType) throws IOException { |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| String type = getFormatNameFromMimeType(mimeType); |
| ImageIO.write(image, type, bos); |
| bos.close(); |
| return bos.toByteArray(); |
| } |
| |
| /** |
| * 1 Extracts the format name from the mime type definition. |
| * |
| * @param mimeType |
| * @return format name of the mime type definition |
| */ |
| private String getFormatNameFromMimeType(String mimeType) { |
| String[] mimeTypeSplit = mimeType.split("/"); |
| return mimeTypeSplit[mimeTypeSplit.length - 1]; |
| } |
| |
| /** |
| * Resizes an image into the specified new width and height if they are not |
| * '0' and convert them from the incoming byte array to a |
| * {@link BufferedImage}. |
| * |
| * @param bytes |
| * @param newWidth |
| * @param newHeight |
| * @return a resized {@link BufferedImage} corresponding to the specified |
| * new width and height |
| * @throws IOException |
| */ |
| private BufferedImage getImage(byte[] bytes, int newWidth, int newHeight) throws IOException { |
| ByteArrayInputStream bis = new ByteArrayInputStream(bytes); |
| BufferedImage image = ImageIO.read(bis); |
| bis.close(); |
| int imageType = 0; |
| if (containsAlphaChannel(image)) { |
| imageType = BufferedImage.TYPE_INT_ARGB; |
| } else if(containsTransparency(image)) { |
| imageType = BufferedImage.TYPE_INT_ARGB_PRE; |
| } else { |
| imageType = BufferedImage.TYPE_INT_RGB; |
| } |
| /* |
| * On resolution '0' the newWidth and newHeight is also '0', because no |
| * scaling is required. But on png files its displaying behaviour on a |
| * BIRT report differs from the behaviour on a dialog view. Creating a |
| * BufferedImage with defined width and height avoids this different |
| * displaying behaviour. |
| */ |
| if (newWidth > 0 && newHeight > 0) { |
| Image scaledImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_AREA_AVERAGING); |
| BufferedImage buffered = new BufferedImage(scaledImage.getWidth(null), scaledImage.getHeight(null), imageType); |
| buffered.getGraphics().drawImage(scaledImage, 0, 0, null); |
| return buffered; |
| } else { |
| BufferedImage buffered = new BufferedImage(image.getWidth(null), image.getHeight(null), imageType); |
| buffered.getGraphics().drawImage(image, 0, 0, null); |
| return buffered; |
| } |
| } |
| |
| private static boolean containsAlphaChannel(BufferedImage image) { |
| return image.getColorModel().hasAlpha(); |
| } |
| |
| private static boolean containsTransparency(BufferedImage image) { |
| for (int i = 0; i < image.getHeight(); i++) { |
| for (int j = 0; j < image.getWidth(); j++) { |
| if (isTransparent(image, j, i)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| public static boolean isTransparent(BufferedImage image, int x, int y) { |
| int pixel = image.getRGB(x, y); |
| return (pixel >> 24) == 0x00; |
| } |
| |
| /** |
| * Creates a new {@link Blob} filled with the specified parameters. |
| * |
| * @param imageBytes |
| * @param fileName |
| * @param resolutionId |
| * @param mimeTypeId |
| * @return |
| */ |
| private BlobDto createImageBlob(byte[] imageBytes, int resolutionId) { |
| BlobDto blobElement = new BlobDto(); |
| blobElement.setData(encodeBase64(imageBytes).getBytes()); |
| blobElement.setResolutionId(resolutionId); |
| return blobElement; |
| } |
| |
| /** |
| * Creates a new {@code List <{@link Blob}>} filled with the specified |
| * parameters. |
| * |
| * @param dataBytes |
| * @return List<Blob>: List of blob objects |
| */ |
| private List<Object> createBlobList(byte[] dataBytes) { |
| List<Object> blobList = new ArrayList<>(); |
| BlobDto blobElement = new BlobDto(); |
| blobElement.setData(dataBytes); |
| blobList.add(blobElement); |
| return blobList; |
| } |
| |
| /** |
| * Provides the existing blob ({@link Blob}) from the database for a |
| * specified blob mapping id and a specified resolution id via JPA or |
| * {@code null} if no blob found. |
| * |
| * @param blobMappingId |
| * @param resolutionId |
| * @return a blob ({@link Blob}) for the specified {@code blobMappingId} and |
| * {@code resolutionId} or {@code null} if no blob found |
| */ |
| private BlobDto getBlobById(String blobMappingId, int resolutionId) { |
| if (blobMappingId != null && resolutionId >= 0) { |
| BlobMappingDto blobMapping = dtoBlobMappingDtoService.get(blobMappingId); |
| if (blobMapping != null) { |
| return getBlobByResolution(resolutionId, blobMapping); |
| } |
| } |
| return null; |
| } |
| |
| private BlobDto getBlobByName(String blobMappingName, int resolutionId, int mimeTypeId) { |
| if (blobMappingName != null && resolutionId >= 0) { |
| IQuery query = new Query(new LAnd(new LCompare.Equal("fileName", blobMappingName), |
| new LCompare.Equal("mimeTypeId", mimeTypeId))); |
| Collection<BlobMappingDto> blobMappings = dtoBlobMappingDtoService.find(query); |
| if (!blobMappings.isEmpty()) { |
| Iterator<BlobMappingDto> iter = blobMappings.iterator(); |
| return getBlobByResolution(resolutionId, iter.next()); |
| } |
| } |
| return null; |
| } |
| |
| private BlobDto getBlobByResolution(int resolutionId, BlobMappingDto blobMapping) { |
| for (BlobDto blob : blobMapping.getBlobsRef()) { |
| if (isImage(blobMapping.getMimeTypeId())) { |
| if (blob.getResolutionId() == resolutionId) { |
| return blob; |
| } |
| } else { |
| return blob; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Checks if the mime type by the specified mime type id {@code mimeTypeId} |
| * corresponds to an image. |
| * |
| * @param mimeTypeId |
| * @return boolean indicating if it is an image |
| */ |
| @Override |
| public boolean isImage(int mimeTypeId) { |
| String mimeType = blobAPI.getMimeTypeContentTypeById(mimeTypeId); |
| return mimeType.startsWith(IBlobTyping.IMAGE_MIME_TYPE_PREFIX); |
| } |
| |
| /** |
| * Checks if the mime type by the specified mime type id {@code mimeTypeId} |
| * corresponds to a pdf file. |
| * |
| * @param mimeTypeId |
| * @return boolean indicating if it is a pdf file |
| */ |
| @Override |
| public boolean isPdf(int mimeTypeId) { |
| return mimeTypeId == IBlobTyping.PDF_MIME_TYPE_ID; |
| } |
| |
| /** |
| * Checks if the mime type by the specified mime type id {@code mimeTypeId} |
| * corresponds to a word file. |
| * |
| * @param mimeTypeId |
| * @return boolean indicating if it is a word file |
| */ |
| @Override |
| public boolean isWord(int mimeTypeId) { |
| return mimeTypeId == IBlobTyping.WORD_DOC_MIME_TYPE_ID || mimeTypeId == IBlobTyping.WORD_DOCX_MIME_TYPE_ID; |
| } |
| |
| /** |
| * Checks if the mime type by the specified mime type id {@code mimeTypeId} |
| * corresponds to a excel file. |
| * |
| * @param mimeTypeId |
| * @return boolean indicating if it is a excel file |
| */ |
| @Override |
| public boolean isExcel(int mimeTypeId) { |
| return mimeTypeId == IBlobTyping.EXCEL_XLS_MIME_TYPE_ID || mimeTypeId == IBlobTyping.EXCEL_XLSX_MIME_TYPE_ID; |
| } |
| |
| /** |
| * Checks if the mime type corresponds to an image. |
| * |
| * @param mimeTypeId |
| * @return boolean indicating if it is an image |
| */ |
| @Override |
| public boolean isImage(String mimeType) { |
| return mimeType.startsWith(IBlobTyping.IMAGE_MIME_TYPE_PREFIX); |
| } |
| |
| /** |
| * Provides the base 64 encoded string representation of a specific blob in |
| * a specific resolution. |
| * |
| * In case of an image mime type it is the base 64 encoded string of the |
| * image and otherwise a defined image for each mime type representing them. |
| * |
| * @param blob |
| * @return |
| */ |
| |
| private String getBase64ValueFromBlob(BlobDto blob) { |
| assert blob != null : "blobDto must not be null"; |
| |
| if (isImage(blob.getBlobMapping().getMimeTypeId())) { |
| return getImageHTMLWithBase64EndodedData(blob.getData(), "", |
| blobAPI.getMimeTypeContentTypeById(blob.getBlobMapping().getMimeTypeId())); |
| } else if (isPdf(blob.getBlobMapping().getMimeTypeId())) { |
| return getImageHTMLWithBase64EndodedData(getDefaultPdfIconBase64String(), |
| blob.getBlobMapping().getFileName(), |
| blobAPI.getMimeTypeContentTypeById(blob.getBlobMapping().getMimeTypeId())); |
| } else if (isExcel(blob.getBlobMapping().getMimeTypeId())) { |
| return getImageHTMLWithBase64EndodedData(getDefaultExcelIconBase64String(), |
| blob.getBlobMapping().getFileName(), |
| blobAPI.getMimeTypeContentTypeById(blob.getBlobMapping().getMimeTypeId())); |
| } else if (isWord(blob.getBlobMapping().getMimeTypeId())) { |
| return getImageHTMLWithBase64EndodedData(getDefaultWordIconBase64String(), |
| blob.getBlobMapping().getFileName(), |
| blobAPI.getMimeTypeContentTypeById(blob.getBlobMapping().getMimeTypeId())); |
| } else { |
| return getImageHTMLWithBase64EndodedData(getDefaultImageBase64String(), blob.getBlobMapping().getFileName(), |
| blobAPI.getMimeTypeContentTypeById(blob.getBlobMapping().getMimeTypeId())); |
| } |
| } |
| |
| /** |
| * Creates a {@link Label} including the representation of a default image |
| * (base64 encoded) as placeholder for a not yet existing blob that could be |
| * visualize. It is primary used when this {@link BlobUploadComponent} is |
| * newly created to upload a blob. Than no blob is available to be |
| * visualized. |
| * |
| * @return a default placeholder image within a Label |
| */ |
| @SuppressWarnings("unused") |
| private Label getDefaultImageLabel() { |
| return new Label(getImageHTMLWithBase64EndodedData(getDefaultImageBase64String(), DEFAULTBLOBFILENAME, |
| DEFAULTBLOBMIMETYPE), ContentMode.HTML); |
| } |
| |
| /** |
| * Provides the HTML-Image-Tag used as input for the {@link Label} of this |
| * ui component based on an specified base64 encoded byte array, the |
| * filename of the blob and it´s mime type. |
| * |
| * @param encodeBase64Bytes |
| * @param fileName |
| * @param mimeType |
| * @return |
| */ |
| private String getImageHTMLWithBase64EndodedData(byte[] encodeBase64Bytes, String fileName, String mimeType) { |
| String encodeBase64 = new String(encodeBase64Bytes); |
| return getImageHTMLWithBase64EndodedData(encodeBase64, fileName, mimeType); |
| } |
| |
| /** |
| * Provides the HTML-Image-Tag used as input for the {@link Label} of this |
| * ui component based on an specified base64 encoded string, the filename of |
| * the blob and it´s mime type. |
| * |
| * @param base64Str |
| * @param fileName |
| * @param mimeType |
| * @return |
| */ |
| private String getImageHTMLWithBase64EndodedData(String base64Str, String fileName, String mimeType) { |
| return "data:" + mimeType + ";base64," + base64Str; |
| } |
| |
| /** |
| * Provides the base64 encoded string representation of the default |
| * placeholder image (Compex-Logo) |
| * |
| * @return the base64 encoded string representation of the default |
| * placeholder image |
| */ |
| private String getDefaultImageBase64String() { |
| return DEFAULT_IMAGE; |
| } |
| |
| /** |
| * Provides the base64 encoded string representation of the default |
| * placeholder pdf icon |
| * |
| * @return the base64 encoded string representation of the default |
| * placeholder pdf icon |
| */ |
| private String getDefaultPdfIconBase64String() { |
| return DEFAULT_PDF_ICON; |
| } |
| |
| /** |
| * Provides the base64 encoded string representation of the default |
| * placeholder word icon |
| * |
| * @return the base64 encoded string representation of the default |
| * placeholder word icon |
| */ |
| private String getDefaultWordIconBase64String() { |
| return DEFAULT_WORD_ICON; |
| } |
| |
| /** |
| * Provides the base64 encoded string representation of the default |
| * placeholder excel icon |
| * |
| * @return the base64 encoded string representation of the default |
| * placeholder excel icon |
| */ |
| private String getDefaultExcelIconBase64String() { |
| return DEFAULT_EXCEL_ICON; |
| } |
| |
| @Override |
| public String getImage(String uuid, int resolutionId) { |
| BlobDto blob = getBlobById(uuid, resolutionId); |
| if (blob != null) { |
| return "<img src=\"" + getBase64ValueFromBlob(blob) + "\" alt=\"Encoded image in Base64\">"; |
| } |
| return null; |
| } |
| |
| @Override |
| public String getBirtImage(String uuid, int resolutionId) { |
| BlobDto blob = getBlobById(uuid, resolutionId); |
| if (blob != null) { |
| return getBase64ValueFromBlob(blob); |
| } |
| return null; |
| } |
| |
| @Override |
| public StreamResource getResource(String uuid, int resolutionId) { |
| BlobDto blob = getBlobById(uuid, resolutionId); |
| if (blob != null) { |
| return new StreamResource(new StreamSource() { |
| private static final long serialVersionUID = 1L; |
| |
| @Override |
| public InputStream getStream() { |
| if (isImage(blob.getBlobMapping().getMimeTypeId())) { |
| return new ByteArrayInputStream(decodeBase64(blob.getData())); |
| } else { |
| return new ByteArrayInputStream(blob.getData()); |
| } |
| } |
| }, blob.getBlobMapping().getFileName()); |
| } |
| return null; |
| } |
| |
| @Override |
| public int getNormalizerResolutionIdByName(String displayResolution) { |
| return blobAPI.getNormalizerResolutionIdByName(displayResolution); |
| } |
| |
| @Override |
| public BufferedImage getBufferedImage(String uuid, int resolutionId) { |
| BlobDto blob = getBlobById(uuid, resolutionId); |
| if (blob != null) { |
| InputStream in = new ByteArrayInputStream(decodeBase64(blob.getData())); |
| try { |
| return ImageIO.read(in); |
| } catch (IOException e) { |
| // bad luck |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public String getBase64Image(String uuid, int resolutionId) { |
| BlobDto blob = getBlobById(uuid, resolutionId); |
| if (blob != null) { |
| return Arrays.toString(blob.getData()); |
| } |
| return null; |
| } |
| |
| @Override |
| public BufferedImage getBufferedImageByName(String name, int resolutionId, String mimeType) { |
| BlobDto blob = getBlobByName(name, resolutionId, blobAPI.getMimeTypeContentTypeId(mimeType)); |
| if (blob != null) { |
| InputStream in = new ByteArrayInputStream(decodeBase64(blob.getData())); |
| try { |
| return ImageIO.read(in); |
| } catch (IOException e) { |
| // bad luck |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public String getBase64ImageByName(String name, int resolutionId, String mimeType) { |
| BlobDto blob = getBlobByName(name, resolutionId, blobAPI.getMimeTypeContentTypeId(mimeType)); |
| if (blob != null) { |
| return Arrays.toString(blob.getData()); |
| } |
| return null; |
| } |
| |
| @Override |
| public byte[] getByteArrayImage(String uuid, int resolutionId) { |
| BlobDto blob = getBlobById(uuid, resolutionId); |
| if (blob != null) { |
| return decodeBase64(blob.getData()); |
| } |
| return null; |
| } |
| } |