
com.sibvisions.rad.ui.vaadin.impl.VaadinImage Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jvxvaadin-server Show documentation
Show all versions of jvxvaadin-server Show documentation
Vaadin UI implementation for JVx
The newest version!
/*
* Copyright 2012 SIB Visions GmbH
*
* Licensed 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.
*
*
* History
*
* 18.10.2012 - [CB] - creation
* 12.08.2013 - [JR] - create resource optionally via UI
* 24.09.2013 - [JR] - support images with byte[]
* 20.10.2013 - [JR] - init(): close stream [BUGFIX]
* 13.09.2015 - [JR] - FontIcon support (FontAwesome, VaadinIcons)
* 27.10.2015 - [JR] - #1501: Creating an instance without name
*/
package com.sibvisions.rad.ui.vaadin.impl;
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.WeakHashMap;
import javax.imageio.ImageIO;
import jvx.rad.ui.IImage;
import com.kbdunn.vaadin.addons.fontawesome.FontAwesome;
import com.sibvisions.rad.ui.LauncherUtil;
import com.sibvisions.rad.ui.vaadin.ext.FontResource;
import com.sibvisions.rad.ui.vaadin.ext.IDownloadStream;
import com.sibvisions.rad.ui.vaadin.ext.INamedResource;
import com.sibvisions.rad.ui.vaadin.ext.VaByteArrayResource;
import com.sibvisions.rad.ui.vaadin.ext.VaCachedResource;
import com.sibvisions.rad.ui.vaadin.ext.VaClassResource;
import com.sibvisions.util.SecureHash;
import com.sibvisions.util.log.LoggerFactory;
import com.sibvisions.util.type.CommonUtil;
import com.sibvisions.util.type.FileUtil;
import com.sibvisions.util.type.ImageUtil;
import com.sibvisions.util.type.StringUtil;
import com.sibvisions.util.type.imageio.MetaDataImage;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.DownloadStream;
import com.vaadin.ui.UI;
/**
* The VaadinImage
class is the vaadin implementation of {@link IImage}.
*
* @author Benedikt Cermak
* @see com.vaadin.ui.Image
*/
public final class VaadinImage extends VaadinResource
implements IImage
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class members
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** the mapping names for images. */
private static HashMap imageMapping = new HashMap();
/** the reverse mapping names for images. */
private static HashMap reverseImageMapping = new HashMap();
/** the cache for created images (saves memory). */
private static HashMap htImageCache = new HashMap();
/** the cache for created images (increases speed). */
private static WeakHashMap> htCreateImageCache = new WeakHashMap>();
/** The widht of the image. **/
private int width;
/** The height of the image. **/
private int height;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialization
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Creates a new instance of VaadinImage
with the given image name.
*
* @param pImageName the path to the Image Resource
*/
protected VaadinImage(String pImageName)
{
super(createResource(pImageName));
init();
}
/**
* Creates a new instance of VaadinImage
with the given image name
* andimage data.
*
* @param pImageName the path to the Image Resource
* @param pData the image data
*/
protected VaadinImage(String pImageName, byte[] pData)
{
super(createResource(pImageName, pData));
init();
}
/**
* Initializes properties.
*/
private void init()
{
if (resource instanceof IDownloadStream)
{
DownloadStream dstream = ((IDownloadStream)resource).getStream();
if (dstream != null)
{
Image img = null;
InputStream stream = null;
try
{
stream = dstream.getStream();
if (stream != null)
{
byte[] byData = FileUtil.getContent(stream);
ByteArrayInputStream bais = new ByteArrayInputStream(byData);
try
{
img = new MetaDataImage(resource.getResourceName(), byData, ImageIO.read(bais)).getImage();
}
finally
{
CommonUtil.close(bais);
}
if (img != null)
{
width = img.getWidth(null);
height = img.getHeight(null);
}
else
{
width = -1;
height = -1;
}
}
else
{
//shouldn't happen
width = -1;
height = -1;
}
}
catch (Exception e) // Invalid jpg causes an IllegalArgumentException, not an IOException, so we should catch all Exceptions
{
LoggerFactory.getInstance(VaadinImage.class).debug("Can't load image!", resource.getResourceName(), e);
//use default
width = -1;
height = -1;
}
finally
{
CommonUtil.close(stream);
}
}
else
{
width = 0;
height = 0;
}
}
else if (resource instanceof FontResource)
{
width = ((FontResource)resource).getSize();
height = width;
}
else
{
width = -1;
height = -1;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Interface Implementation
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* {@inheritDoc}
*/
public String getImageName()
{
return resource.getResourceName();
}
/**
* {@inheritDoc}
*/
public int getWidth()
{
return width;
}
/**
* {@inheritDoc}
*/
public int getHeight()
{
return height;
}
/**
* {@inheritDoc}
*/
public void saveAs(OutputStream pOut, ImageType pType) throws IOException
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// User-defined methods
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Creates the resource for the image.
*
* @param pImageName the image name
* @return the resource
*/
public static INamedResource createResource(String pImageName)
{
String sMapping = getImageMapping(pImageName);
if (sMapping != null
&& (sMapping.startsWith("FontAwesome.") || sMapping.startsWith("VaadinIcons.")))
{
HashMap hmpProp = LauncherUtil.splitImageProperties(sMapping.substring(12));
FontResource res;
String sName = hmpProp.remove("name").toUpperCase();
sName = sName.replace("-", "_");
try
{
if (Character.isDigit(sName.charAt(0)))
{
sName = "_" + sName;
}
if (sMapping.startsWith("FontAwesome."))
{
res = new FontResource(sMapping, FontAwesome.valueOf(sName));
}
else
{
res = new FontResource(sMapping, VaadinIcons.valueOf(sName));
}
}
catch (IllegalArgumentException iae)
{
//e.g. different FontIcon versions!
LoggerFactory.getInstance(VaadinImage.class).error(iae);
return null;
}
String sStyle = hmpProp.remove("style");
if (StringUtil.isEmpty(sStyle))
{
//fi means FontIcon
sStyle = "fi_" + getStyleName(sName);
}
res.setStyleName(sStyle);
String sKey;
String sValue;
String sMapProp = hmpProp.remove("mapping");
//mark the resource "mapped". This makes it possible to define general css settings
res.setMapped(sMapping != pImageName || Boolean.parseBoolean(sMapProp));
for (Entry entry : hmpProp.entrySet())
{
sKey = entry.getKey();
sValue = entry.getValue();
if ("size".equals(sKey))
{
//size doesn't work!
sKey = "font-size";
try
{
int iSize = Integer.parseInt(sValue);
res.setSize(iSize);
//default unit: pixel
sValue += "px";
}
catch (NumberFormatException nfe)
{
//value contains unit
}
}
res.addCustomStyleProperty(sKey, sValue);
}
return res;
}
if (sMapping == null)
{
return null;
}
else
{
int iPos = sMapping.indexOf(";");
String sResource = sMapping;
String sStyle = null;
if (iPos >= 0)
{
sResource = sMapping.substring(0, iPos);
HashMap hmpProps = LauncherUtil.splitImageProperties(sMapping.substring(0));
sStyle = hmpProps.get("style");
}
if (sStyle == null)
{
sStyle = getStyleName(sResource);
}
return createResource(sResource, sStyle);
}
}
/**
* Creates the resource for the image.
*
* @param pResourceName the resource name/path
* @param pStyleName the CSS name
* @return the resource
*/
private static INamedResource createResource(String pResourceName, String pStyleName)
{
if (pResourceName == null)
{
return null;
}
UI ui = UI.getCurrent();
if (ui == null || !(ui instanceof VaadinUI))
{
return new VaClassResource(pResourceName, pStyleName);
}
else
{
VaCachedResource res = ((VaadinUI)UI.getCurrent()).createCachedResource(pResourceName);
res.setStyleName(pStyleName);
return res;
}
}
/**
* Creates the resource for the image, using the given image data.
*
* @param pName the image name (maybe a resource name)
* @param pData the image data. If image data is null
a resource with the
* given name will be searched
* @return the image resource
*/
private static INamedResource createResource(String pName, byte[] pData)
{
if (pName == null)
{
return null;
}
String sStyleName = getStyleName(pName);
if (pData == null)
{
return createResource(pName, sStyleName);
}
UI ui = UI.getCurrent();
if (ui == null || !(ui instanceof VaadinUI))
{
return new VaByteArrayResource(pName, pData, sStyleName);
}
else
{
VaCachedResource res = ((VaadinUI)UI.getCurrent()).createCachedResource(pName, pData);
res.setStyleName(sStyleName);
return res;
}
}
/**
* Returns the name of the image.
*
* @return the name of the image.
*/
public String getName()
{
return resource.getResourceName();
}
/**
* Returns the style name.
*
* @param pName the name.
* @return the style name.
*/
public static String getStyleName(String pName)
{
String name = reverseImageMapping.get(pName);
if (name == null)
{
name = pName;
}
if (name != null)
{
int lastIndexFirst = name.lastIndexOf("/");
int lastIndexLast = name.lastIndexOf(".");
if (lastIndexFirst < 0)
{
lastIndexFirst = 0;
}
else
{
lastIndexFirst++;
}
if (lastIndexLast < 0)
{
lastIndexLast = name.length();
}
name = StringUtil.convertToName(name.substring(lastIndexFirst, lastIndexLast)).toLowerCase();
}
return name;
}
/**
* Returns the style name.
*
* @return the style name.
*/
public String getStyleName()
{
return resource.getStyleName();
}
/**
* Gets the image name for the given mapping name.
*
* @param pMappingName the mapping name.
* @return the image name.
*/
public static String getImageMapping(String pMappingName)
{
if (pMappingName == null)
{
return null;
}
String imgName = imageMapping.get(pMappingName);
if (imgName == null)
{
return pMappingName;
}
else
{
return imgName;
}
}
/**
* Sets the image name for the given mapping name.
*
* @param pMappingName the mapping name.
* @param pImageName the image name.
*/
public static void setImageMapping(String pMappingName, String pImageName)
{
if (pMappingName == null)
{
if (pImageName != null)
{
VaadinUI.removeCachedResource(pImageName);
}
}
else
{
if (pImageName == null)
{
String sResName = imageMapping.remove(pMappingName);
reverseImageMapping.remove(sResName);
htImageCache.remove(pMappingName);
}
else
{
String sResName = imageMapping.put(pMappingName, pImageName);
reverseImageMapping.remove(sResName);
reverseImageMapping.put(pImageName, pMappingName);
htImageCache.remove(pMappingName);
}
}
}
/**
* Gets all used mapping names.
*
* @return the mapping names.
*/
public static String[] getImageMappingNames()
{
return imageMapping.keySet().toArray(new String[imageMapping.size()]);
}
/**
* Creates a new {@link VaadinImage} instance based on the image name.
*
* @param pImageName the path to the Image Resource
* @return the image or null
if the image name is null
*/
public static VaadinImage getImage(String pImageName)
{
// don't load null resources
if (pImageName == null)
{
return null;
}
VaadinImage image = htImageCache.get(pImageName);
if (image == null)
{
image = new VaadinImage(pImageName);
if (image != null)
{
htImageCache.put(pImageName, image);
}
}
return image;
}
/**
* Creates a new {@link VaadinImage} instance based on the image name and image data.
*
* @param pImageName the path to the Image Resource
* @param pData the image data
* @return the image or null
if the image name is null
*/
public static VaadinImage getImage(String pImageName, byte[] pData)
{
if (pData == null)
{
//maybe the image name is mapped
return getImage(pImageName);
}
WeakReference wrImage = htCreateImageCache.get(pData);
VaadinImage image = null;
if (wrImage != null)
{
image = wrImage.get();
}
if (image == null)
{
if (pImageName != null)
{
image = new VaadinImage(pImageName, pData);
}
else
{
try
{
String sTempName = "ondemand_" + SecureHash.getHash(SecureHash.MD5, pData); // Faster but not loadbalancable would be: System.identityHashCode(pData);
switch (ImageUtil.getImageFormat(pData))
{
case BMP:
sTempName += ".bmp";
break;
case GIF:
sTempName += ".gif";
break;
case PNG:
sTempName += ".png";
break;
case TIFF:
sTempName += ".tif";
break;
case WMF:
sTempName += ".wmf";
break;
case JPG:
case JPG2000:
sTempName += ".jpg";
break;
default:
throw new RuntimeException("Unsupported image type!");
}
image = new VaadinImage(sTempName, pData);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
htCreateImageCache.put(pData, new WeakReference(image));
}
if (pImageName != null)
{
htImageCache.put(pImageName, image);
}
return image;
}
} // VaadinImage
© 2015 - 2025 Weber Informatics LLC | Privacy Policy