/**
* License Agreement.
*
* JBoss RichFaces - Ajax4jsf Component Library
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.richfaces.renderkit.html;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.Serializable;
import javax.faces.FacesException;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import org.ajax4jsf.resource.GifRenderer;
import org.ajax4jsf.resource.ImageRenderer;
import org.ajax4jsf.resource.InternetResourceBase;
import org.ajax4jsf.resource.JpegRenderer;
import org.ajax4jsf.resource.PngRenderer;
import org.ajax4jsf.resource.ResourceContext;
import org.ajax4jsf.resource.ResourceRenderer;
import org.ajax4jsf.util.HtmlColor;
import org.richfaces.component.UIPaint2D;
/**
* Resource for create image by managed bean method
* @author asmirnov@exadel.com (latest modification by $Author: aizobov $)
* @version $Revision: 1.4 $ $Date: 2007/02/28 10:35:23 $
*
*/
public class Paint2DResource extends InternetResourceBase {
private static final ImageRenderer[] _renderers= {new GifRenderer(), new JpegRenderer(), new PngRenderer()};
private static final ThreadLocal threadLocalContentType = new ThreadLocal();
/* (non-Javadoc)
* @see org.ajax4jsf.resource.InternetResourceBase#getRenderer()
*/
public ResourceRenderer getRenderer() {
return _renderers[0];
}
public ResourceRenderer getRenderer(ResourceContext arg0) {
return getRenderer();
}
/* (non-Javadoc)
* @see org.ajax4jsf.resource.InternetResourceBase#isCacheable()
*/
public boolean isCacheable() {
return false;
}
/* (non-Javadoc)
* @see org.ajax4jsf.resource.InternetResourceBase#requireFacesContext()
*/
public boolean requireFacesContext() {
// work in context
return true;
}
/* (non-Javadoc)
* @see org.ajax4jsf.resource.InternetResourceBase#getDataToStore(javax.faces.context.FacesContext, java.lang.Object)
*/
protected Object getDataToStore(FacesContext context, Object data) {
if (data instanceof UIPaint2D) {
UIPaint2D paint2D = (UIPaint2D) data;
ImageData dataToStore = new ImageData();
dataToStore._width = paint2D.getWidth();
dataToStore._height = paint2D.getHeight();
dataToStore._data = paint2D.getData();
dataToStore._paint = UIComponentBase.saveAttachedState(context, paint2D.getPaint());
String format = paint2D.getFormat();
if("jpeg".equalsIgnoreCase(format)) {
dataToStore._format = 1;
} else if("png".equalsIgnoreCase(format)) {
dataToStore._format = 2;
}
String bgColor = paint2D.getBgcolor();
try {
dataToStore._bgColor = HtmlColor.decode(bgColor).getRGB();
} catch (Exception e) {}
return dataToStore;
} else {
throw new FacesException("Data for painting image resource not instance of UIPaint2D");
}
}
private static class ImageData implements Serializable {
private static final long serialVersionUID = 4452040100045367726L;
int _width=1;
int _height = 1;
Object _data;
int _format = 0;
Object _paint;
/*
* init color with transparent by default
*/
int _bgColor = 0;
}
/**
* Primary calculation of image dimensions - used when HTML code is generated
* to render IMG's width and height
* Subclasses should override this method to provide correct sizes of rendered images
* @param facesContext
* @return dimensions of the image to be displayed on page
*/
public Dimension getDimensions(FacesContext facesContext, Object data){
if (data instanceof UIPaint2D) {
UIPaint2D paint2D = (UIPaint2D) data;
return new Dimension(paint2D.getWidth(),paint2D.getHeight());
}
return new Dimension(1,1);
}
/**
* Secondary calculation is used basically by {@link getImage} method
* @param resourceContext
* @return
*/
protected Dimension getDimensions(ResourceContext resourceContext){
ImageData data = (ImageData) restoreData(resourceContext);
return new Dimension(data._width,data._height);
}
/* (non-Javadoc)
* @see org.ajax4jsf.resource.InternetResourceBase#send(javax.faces.context.FacesContext, java.lang.Object)
*/
public void send(ResourceContext context) throws IOException {
ImageData data = (ImageData) restoreData(context);
ImageRenderer renderer = _renderers[data._format];
FacesContext facesContext = FacesContext.getCurrentInstance();
try {
BufferedImage image = renderer.createImage(data._width,data._height);
Graphics2D graphics = image.createGraphics();
try {
if (data._bgColor != 0) {
Color color = new Color(data._bgColor);
graphics.setBackground(color);
graphics.clearRect(0, 0, data._width, data._height);
}
MethodBinding paint = (MethodBinding) UIComponentBase.restoreAttachedState(facesContext, data._paint);
paint.invoke(facesContext, new Object[] {graphics,data._data});
} finally {
if (graphics != null) {
graphics.dispose();
}
}
renderer.sendImage(context, image);
} catch (Exception e) {
// log.error("Error send image from resource "+context.getPathInfo(),e);
throw new FacesException("Error send image ",e);
}
}
public String getContentType(ResourceContext context) {
Object contentType = threadLocalContentType.get();
if (contentType != null) {
return (String) contentType;
} else {
return super.getContentType(context);
}
}
/* (non-Javadoc)
* @see org.ajax4jsf.resource.InternetResourceBase#sendHeaders(org.ajax4jsf.resource.ResourceContext)
*/
public void sendHeaders(ResourceContext context) {
ImageData data = (ImageData) restoreData(context);
ImageRenderer renderer = _renderers[data._format];
threadLocalContentType.set(renderer.getContentType());
super.sendHeaders(context);
threadLocalContentType.set(null);
}
}