Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Open SUIT - Simple User Interface Toolkit
*
* Copyright (c) 2009 EBM Websourcing, http://www.ebmwebsourcing.com/
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.ow2.opensuit.xml.chart;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.encoders.EncoderUtil;
import org.jfree.chart.encoders.ImageFormat;
import org.jfree.chart.imagemap.ImageMapUtilities;
import org.jfree.chart.plot.Plot;
import org.jfree.ui.RectangleInsets;
import org.ow2.opensuit.core.session.OpenSuitSession;
import org.ow2.opensuit.core.session.PageContext;
import org.ow2.opensuit.core.util.HtmlUtils;
import org.ow2.opensuit.core.util.UrlBuilder;
import org.ow2.opensuit.xml.base.Application;
import org.ow2.opensuit.xml.base.binding.Do;
import org.ow2.opensuit.xml.base.binding.Expression;
import org.ow2.opensuit.xml.base.html.IFrame;
import org.ow2.opensuit.xml.base.html.IView;
import org.ow2.opensuit.xml.base.page.IPage;
import org.ow2.opensuit.xml.interfaces.IBeanProvider;
import org.ow2.opensuit.xmlmap.annotations.XmlAncestor;
import org.ow2.opensuit.xmlmap.annotations.XmlAttribute;
import org.ow2.opensuit.xmlmap.annotations.XmlChild;
import org.ow2.opensuit.xmlmap.annotations.XmlChildren;
import org.ow2.opensuit.xmlmap.annotations.XmlDoc;
import org.ow2.opensuit.xmlmap.annotations.XmlElement;
import org.ow2.opensuit.xmlmap.interfaces.IInitializable;
import org.ow2.opensuit.xmlmap.interfaces.IInitializationSupport;
import org.ow2.opensuit.xmlmap.interfaces.IInstantiationContext;
@XmlDoc("This is the base abstract component that enables JFreeChart integration in open SUIT.")
@XmlElement
public abstract class BaseChart implements IView, IInitializable, IBeanProvider
{
protected Log logger = LogFactory.getLog(this.getClass());
@XmlAncestor
protected Application root;
@XmlAncestor
private IBeanProvider parentProvider;
@XmlDoc("Image width (in pixels).")
@XmlAttribute(name="Width", required=true)
private int width;
@XmlDoc("Image height (in pixels).")
@XmlAttribute(name="Height", required=true)
private int height;
@XmlDoc("Determines whether the char displays the legend." +
"Default: true.")
@XmlAttribute(name="ShowLegend", required=false)
private boolean showLegend= true;
@XmlDoc("Enables chart auto-reload. " +
"This expression returns the auto-reload time interval (in milliseconds). " +
"A null value (0) disables the auto-reload behavior. " +
"Note: with auto-reload behavior, the 'ChartTime' expression should always return System.currentTimeMillis()")
@XmlChild(name="AutoReloadInterval", required=false)
protected Expression autoReloadInterval;
@XmlDoc("The chart time. " +
"This expression returns a timestamp (long) representing the latest time when data " +
"required to produce the chart was computed.")
@XmlChild(name="ChartTime")
protected Expression chartTime;
@XmlDoc("The chart title. " +
"This will be displayed inside the chart image, and will also be used as the image filename.")
@XmlChild(name="Title")
protected Expression title;
@XmlDoc("Some actions to perform at prerender time. " +
"This is where you may use the $control object to invalidate() the cached chart.")
@XmlChildren(name="OnPreRender", minOccurs=0)
private Do[] onPreRender;
// --- [+] IIdentifiable implementation
@XmlAncestor
private IPage page;
@XmlAncestor
private IFrame frame;
public String getPathID()
{
if(page != null)
return page.getPath()+"/Chart";
else
return "/"+frame.getName()+"/Chart";
}
// --- [-] IIdentifiable implementation
public void initialize(IInitializationSupport initSupport, IInstantiationContext instContext)
{
root.registerRequestHandler(getPathID(), this);
if(chartTime != null && initSupport.initialize(chartTime))
{
if(!chartTime.isConvertible(Long.class))
initSupport.addValidationMessage(this, "ChartDate", IInitializationSupport.ERROR, "Expression 'ChartDate' must return a long (timestamp).");
}
if(autoReloadInterval != null && initSupport.initialize(autoReloadInterval))
{
if(!autoReloadInterval.isConvertible(Integer.class))
initSupport.addValidationMessage(this, "AutoReloadInterval", IInitializationSupport.ERROR, "Expression 'AutoReloadInterval' must return a number.");
}
}
protected String getTitle(HttpServletRequest request)
{
try
{
return title.invoke(request, String.class);
}
catch (Exception e)
{
return "chart";
}
}
public void preRender(HttpServletRequest request) throws Exception
{
if(onPreRender != null)
{
for(Do d : onPreRender)
d.invoke(request);
}
}
public void render(HttpServletRequest request, HttpServletResponse response) throws Exception
{
int autoReloadInterval = 0;
if(this.autoReloadInterval != null)
autoReloadInterval = this.autoReloadInterval.invoke(request, Integer.class);
String titleStr = title.invoke(request, String.class);
String fileNameNoExt = titleStr;// TODO: encode ?
int w = width;
int h = height;
UrlBuilder url = root.createServiceUrl(request, this, "serveImage", fileNameNoExt+".png");
url.setParameter("w", String.valueOf(w));
url.setParameter("h", String.valueOf(h));
url.setParameter("title", titleStr);
/* No: not supported
UrlBuilder urlLow = root.createServiceUrl(request, this, "serveWaiting", fileNameNoExt+".png");
urlLow.setParameter("w", String.valueOf(w));
urlLow.setParameter("h", String.valueOf(h));
*/
// --- make chart data and compute image
CachedChartData data = getData(request, titleStr);
// --- in order not to stuck the page rendering (but preferably the chart image download),
// --- we just compute the image map here, and not the image (much faster!)
// ChartRenderingInfo info = new ChartRenderingInfo();
// data.newImage = makeImage(data.chart, w, h, info);
ChartRenderingInfo info = computeInfo(data.chart, w, h);
String imgName = HtmlUtils.formatId(fileNameNoExt);
String mapName = imgName+"_map";
// --- Render html
PrintWriter writer = response.getWriter();
if(autoReloadInterval > 0)
{
// --- include Common.js (for newXHR())
HtmlUtils.includeBaseJavaScript(request, response, "Common.js");
// --- include Chart.js
HtmlUtils.includeJavaScript(request, response, "org/ow2/opensuit/xml/chart/Chart.js");
UrlBuilder urlMap = root.createServiceUrl(request, this, "reloadMap", mapName);
urlMap.setParameter("w", String.valueOf(w));
urlMap.setParameter("h", String.valueOf(h));
urlMap.setParameter("name", mapName);
urlMap.setParameter("title", titleStr);
// --- write script that sets the interval
writer.println("");
}
// --- render image and map
// ImageMapUtilities.writeImageMap(writer, mapName, info, new StandardToolTipTagFragmentGenerator(), new URLFragmentGenerator());
ImageMapUtilities.writeImageMap(writer, mapName, info);
// --- render image
writer.print("");
}
/**
* This method computes the Chart Rendering Info, required to produce the
* image map.
* This method is much faster than making the image, as it relies on an
* inoperant Graphics object.
* @param chart the chart model
* @param w image width
* @param h image height
* @return
*/
private ChartRenderingInfo computeInfo(JFreeChart chart, int w, int h)
{
long start = System.currentTimeMillis();
try
{
ChartRenderingInfo info = new ChartRenderingInfo();
BufferedImage img = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = new InoperantGraphics(img.createGraphics());
chart.draw(g2, new Rectangle2D.Double(0, 0, w, h), info);
return info;
}
finally
{
long end = System.currentTimeMillis();
logger.debug("Chart info ("+w+"x"+h+") computed in "+(end-start)+" ms");
}
}
/**
* This method processes the chart image with given with and height
* @param chart the chart model
* @param w image width
* @param h image height
* @param info the chart rendering info to populate (may be null)
* @return
*/
private BufferedImage makeImage(JFreeChart chart, int w, int h, ChartRenderingInfo info)
{
long start = System.currentTimeMillis();
try
{
return chart.createBufferedImage(w, h, info);
}
finally
{
long end = System.currentTimeMillis();
logger.debug("Chart image ("+w+"x"+h+") computed in "+(end-start)+" ms");
}
}
private JFreeChart makeChart(HttpServletRequest request, String title) throws Exception
{
logger.debug("makeChart('"+title+"')");
Plot plot = makePlot(request);
plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
// --- now we know for sure we have to recompute the chart
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, showLegend);
// TODO? ChartFactory.getChartTheme().apply(chart);
return chart;
}
private CachedChartData getData(HttpServletRequest request, String title) throws Exception
{
// --- retrieve from cache
CachedChartData data = getCache(request);
if(data != null && data.newImage != null)
{
// --- this is the image request right after having rendered the HTML page
// --- do not recompute in any case
logger.debug("getData(): a new image is waiting to be served: use cached image.");
return data;
}
long time = chartTime.invoke(request, Long.class);
if(data != null && data.time >= time)
{
logger.debug("getData(): cached chart still valid. Reuse cache.");
return data;
}
// --- need to compute
logger.debug("getData(): compute chart.");
Plot plot = makePlot(request);
plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
// --- now we know for sure we have to recompute the chart
data = new CachedChartData();
data.chart = makeChart(request, title);
data.time = time;
// --- store in cache and return
setCache(request, data);
return data;
}
public void reloadMap(HttpServletRequest request, HttpServletResponse response) throws Exception
{
int w = Integer.parseInt(request.getParameter("w"));
int h = Integer.parseInt(request.getParameter("h"));
String mapName = request.getParameter("name");
String title = request.getParameter("title");
// --- clear cached chart and reload
removeCache(request);
CachedChartData data = getData(request, title);
// --- here we know this is an Ajax request, so we can afford computing the real image
// --- as it's asynchronous, and the browser will request for it right away
// ChartRenderingInfo info = computeInfo(data.chart, w, h);
ChartRenderingInfo info = new ChartRenderingInfo();
data.newImage = makeImage(data.chart, w, h, info);
OpenSuitSession session = OpenSuitSession.getSession(request);
response.setContentType("text/html;charset="+session.getLocaleConfig().getCharSet());
// iResponse.setHeader("Cache-Control", "no-store"); //HTTP 1.1
response.setHeader("Cache-Control", "no-cache"); //HTTP 1.1
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
PrintWriter writer = response.getWriter();
// --- write map
ImageMapUtilities.writeImageMap(writer, mapName, info);
writer.flush();
writer.close();
}
public void serveWaiting(HttpServletRequest request, HttpServletResponse response) throws Exception
{
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
if(ifModifiedSince > 0)
{
// --- 304: not modified
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
// --- compute image
int w = Integer.parseInt(request.getParameter("w"));
int h = Integer.parseInt(request.getParameter("h"));
// --- create and draw waiting image
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
Graphics g = img.getGraphics();
// TODO (houglass?)
g.setColor(Color.red);
g.fillRect(0, 0, w, h);
long now = System.currentTimeMillis();
// --- force Pragma and Cache-Control headers
// if servlet is in a security-constraint (web.xml), the servlet container
// may set Pragma: no-cache and CacheControl: no-cache
response.setHeader("Pragma", "");
response.setHeader("Cache-Control", "public");
response.addHeader("Cache-Control", "max-age=86400");//one day
// --- set Last-Modified, Date and Expires
response.setDateHeader("Last-Modified", now);
response.setDateHeader("Date", now);
// not needed with max-age response.setDateHeader("Expires", now + (EXPIRATION_DELAY_SEC * 1000)); // 1 day
/*
// --- disable cache
response.setHeader("Cache-Control", "no-cache"); //HTTP 1.1
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
*/
// --- set mime type
response.setContentType("image/png");
OutputStream output = response.getOutputStream();
// --- write image bytes
EncoderUtil.writeBufferedImage(img, ImageFormat.PNG, output);
output.flush();
output.close();
}
public void serveImage(HttpServletRequest request, HttpServletResponse response) throws Exception
{
String titleStr = request.getParameter("title");
int w = Integer.parseInt(request.getParameter("w"));
int h = Integer.parseInt(request.getParameter("h"));
CachedChartData data = getData(request, titleStr);
// --- retrieve possible cached image (computed when rendering the image map)
BufferedImage cachedImage = data.newImage;
// --- clear cached image
data.newImage = null;
// --- manage cache
long lastModified = data.time;
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
// --- date headers don't contain milliseconds: test the seconds value
if((lastModified / 1000L) <= (ifModifiedSince / 1000L))
{
// --- 304: not modified
logger.debug("serveImage(): client cache still valid: not modified (304)");
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
if(ifModifiedSince == 0)
logger.debug("serveImage(): no client cache: serve.");
else
logger.debug("serveImage(): client cache obsolete: serve.");
// --- set cache info
long now = System.currentTimeMillis();
// --- force Pragma and Cache-Control headers
// if servlet is in a security-constraint (web.xml), the servlet container
// may set Pragma: no-cache and CacheControl: no-cache
response.setHeader("Pragma", "");
response.setHeader("Cache-Control", "public");
response.addHeader("Cache-Control", "must-revalidate");
response.addHeader("Cache-Control", "max-age=0");
// --- set Last-Modified, Date and Expires
response.setDateHeader("Last-Modified", lastModified);
response.setDateHeader("Date", now);
// not needed with max-age response.setDateHeader("Expires", now + (EXPIRATION_DELAY_SEC * 1000)); // 1 day
/*
// --- disable cache
response.setHeader("Cache-Control", "no-cache"); //HTTP 1.1
response.setHeader("Pragma", "no-cache"); //HTTP 1.0
response.setDateHeader("Expires", 0); //prevents caching at the proxy server
*/
// --- set mime type
response.setContentType("image/png");
OutputStream output = response.getOutputStream();
if(cachedImage == null)
cachedImage = makeImage(data.chart, w, h, null);
// --- write image bytes
EncoderUtil.writeBufferedImage(cachedImage, ImageFormat.PNG, output);
output.flush();
output.close();
}
public abstract Plot makePlot(HttpServletRequest request) throws Exception;
// =======================================================================
// === Cache Management
// =======================================================================
private static class CachedChartData implements Serializable
{
private static final long serialVersionUID = 1L;
public BufferedImage newImage;
public JFreeChart chart;
public long time;
}
private CachedChartData getCache(HttpServletRequest request)
{
OpenSuitSession session = OpenSuitSession.getSession(request);
PageContext ctx = session.getCurrentPageContext();
HashMap