/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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 General Public License for more details. * * * Copyright 2005 - 2008 Pentaho Corporation. All rights reserved. * * @created Aug 15, 2005 * @author James Dixon */ package org.pentaho.platform.uifoundation.chart; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.pentaho.platform.api.engine.IActionSequenceResource; import org.pentaho.platform.api.engine.IPentahoUrlFactory; import org.pentaho.platform.api.repository.ISolutionRepository; import org.pentaho.platform.engine.core.solution.ActionInfo; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.actionsequence.ActionSequenceResource; import org.pentaho.platform.uifoundation.component.xml.XmlComponent; import org.pentaho.platform.uifoundation.messages.Messages; /** * This class is a Pentaho user interface component. <p/> It generates dial * images that can be embedded into JSPs, portals or other HTML supporting user * interface. <p/> * <ol> * <li> The creating object sets the width, height, the type of the dial, and * the name of the dial.xml file that contains the definition of the dial.</li> * <li> This class creates an instance of a DialWidgetDefinition using the * specified XML definition file. The XML files are located in the solution * folders and have .dial.xml extenstions. The dial XML files define the * attributes that define how the dial looks. </li> * <li> It uses the JFreeChartEngine to create an image of the dial.</li> * <li> Once the image has been created this class creates an XML document * describing the dial * <li> It uses an XSL to tranforms the XML description into HTML. * </ol> * This is an example image */ public class DashboardWidgetComponent extends XmlComponent { /** * */ private static final long serialVersionUID = 3060729271469984040L; public static final int TYPE_DIAL = 1; public static final int TYPE_THERMOMETER = 2; private static final Log logger = LogFactory.getLog(DashboardWidgetComponent.class); private int type; private double value = DashboardWidgetComponent.TYPE_DIAL; private String definitionPath; private String title = ""; //$NON-NLS-1$ private String units = ""; //$NON-NLS-1$ private int width; private int height; /** * Creates a DashboardWidgetComponent. * <p> * After creating an instance of this class <CODE>validate</CODE> should * be called. * * @param type * The type of the widget, currently only TYPE_DIAL is supported * @param definitionPath * The path and name of the XML definition of the dial * @param width * The width of the image to be created * @param height * The height of the image to be created * @param urlFactory * The urlFactory for the content * @param messages * The messages list for any logger messages */ public DashboardWidgetComponent(final int type, final String definitionPath, final int width, final int height, final IPentahoUrlFactory urlFactory, final List messages) { super(urlFactory, messages, null); this.type = type; this.definitionPath = definitionPath; this.width = width; this.height = height; ActionInfo info = ActionInfo.parseActionString(definitionPath); if (info != null) { setSourcePath(info.getSolutionName() + File.separator + info.getPath()); } // Set the XSL file to be used to generate the HTML setXsl("text/html", "DialWidget.xsl"); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Sets the value to be displayed by the dial. * * @param value * The dial value */ public void setValue(final double value) { this.value = value; } /** * Sets the title for the dial * * @param title * The title of the dial */ public void setTitle(final String title) { this.title = title; } /** * Sets the unit for the dial value * * @param units * The dial units */ public void setUnits(final String units) { this.units = units; } /** * Gets the logger for his component. * * @return logger This component's logger */ @Override public Log getLogger() { return DashboardWidgetComponent.logger; } /** * Validate that this component can generate the requested dial */ @Override public boolean validate() { // TODO return true; } /** * Create a dial image. * <ul> * <li>Load the specified XML document describing the dial definition</li> * <li>Create a dial definition object from the XML definition</li> * <li>Use the JFreeChartEngine to create a dial image</li> * <li>Create an XML document describing the dial</li> * <li>Return the XML document</li> * </ul> * * @return The XML document describing this dial */ @Override public Document getXmlContent() { WidgetDefinition widget = null; if (type == DashboardWidgetComponent.TYPE_DIAL) { // load the XML document that defines the dial IActionSequenceResource resource = new ActionSequenceResource(title, IActionSequenceResource.SOLUTION_FILE_RESOURCE, "text/xml", //$NON-NLS-1$ definitionPath); Document dialDefinition = null; try { dialDefinition = PentahoSystem.get(ISolutionRepository.class, getSession()).getResourceAsDocument(resource, ISolutionRepository.ACTION_EXECUTE); } catch (IOException e) { error(Messages.getInstance().getErrorString("Widget.ERROR_0002_INVALID_RESOURCE", definitionPath), e); //$NON-NLS-1$ } if (dialDefinition == null) { error(Messages.getInstance().getErrorString("Widget.ERROR_0002_INVALID_RESOURCE", definitionPath)); //$NON-NLS-1$ return null; } // create a dial definition from the XML definition widget = new DialWidgetDefinition(dialDefinition, 0, width, height, getSession()); if (widget != null) { // set the value to be displayed on the dial widget.setValue(new Double(value)); } else { error(Messages.getInstance().getString("Widget.ERROR_0001_COULD_NOT_CREATE")); //$NON-NLS-1$ return null; } } /* * else if( type == TYPE_THERMOMETER ) { // load the XML document that * defines the thermometer * * ActionResource resource = new ActionResource( title, * IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", //$NON-NLS-1$ * PentahoSystem.getApplicationContext().getSolutionPath( definitionPath ) ); * //$NON-NLS-1$ Document thermometerDefinition = null; try { * thermometerDefinition = PentahoSystem.getResourceAsDocument( resource ); } * catch (IOException e) {} // create a dial definition from the XML * definition widget = createThermometer( thermometerDefinition ); * * if( widget != null ) { // set the value to be displayed on the dial * widget.setValue( new Double(value) ); // Set the XSL file to be used * to generate the HTML setXsl( "text/html", "DialWidget.xsl" ); * //$NON-NLS-1$ //$NON-NLS-2$ } else { error( * Messages.getInstance().getString("Widget.ERROR_0001_COULD_NOT_CREATE") ); * //$NON-NLS-1$ return null; } } */ if (widget == null) { error(Messages.getInstance().getString("Widget.ERROR_0001_COULD_NOT_CREATE")); //$NON-NLS-1$ return null; } // create an image for the dial using the JFreeChart engine StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); // create temporary file names String solutionDir = "system/tmp/"; //$NON-NLS-1$ String fileNamePrefix = "tmp_pie_"; //$NON-NLS-1$ String extension = ".png"; //$NON-NLS-1$ String fileName = null; String filePathWithoutExtension = null; try { File file = PentahoSystem.getApplicationContext().createTempFile(getSession(), fileNamePrefix, extension, true); fileName = file.getName(); filePathWithoutExtension = solutionDir + fileName.substring(0, fileName.indexOf('.')); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } String dialTitle = ""; //$NON-NLS-1$ JFreeChartEngine.saveChart(widget, dialTitle, units, filePathWithoutExtension, width, height, JFreeChartEngine.OUTPUT_PNG, printWriter, this); // Create a document that describes the result Document result = DocumentHelper.createDocument(); String baseUrl = PentahoSystem.getApplicationContext().getBaseUrl(); setXslProperty("baseUrl", baseUrl); //$NON-NLS-1$ Element root = result.addElement("widget"); //$NON-NLS-1$ root.addElement("title").setText(title); //$NON-NLS-1$ root.addElement("units").setText(units); //$NON-NLS-1$ root.addElement("width").setText(Integer.toString(width)); //$NON-NLS-1$ root.addElement("height").setText(Integer.toString(height)); //$NON-NLS-1$ Element valueNode = root.addElement("value");//$NON-NLS-1$ valueNode.setText(Double.toString(value)); valueNode.addAttribute("in-image", Boolean.toString(widget.getValueFont() != null)); //$NON-NLS-1$ root.addElement("image").setText(fileName); //$NON-NLS-1$ return result; } public void dispose() { } }