ChartHelper.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.pentaho.ui |
![]() |
![]() |
Pentaho |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* Copyright 2006 Pentaho Corporation. All rights reserved.
* This software was developed by Pentaho Corporation and is provided under the terms
* of the Mozilla Public License, Version 1.1, or any later version. You may not use
* this file except in compliance with the license. If you need a copy of the license,
* please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
* BI Platform. The Initial Developer is Pentaho Corporation.
*
* Software distributed under the Mozilla Public License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
* the license for the specific language governing your rights and limitations.
*
* @created Apr 17, 2006
* @author James Dixon
*/
package org.pentaho.ui;
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.dom4j.Document;
import org.dom4j.Node;
import org.pentaho.commons.connection.DataUtilities;
import org.pentaho.commons.connection.IPentahoConnection;
import org.pentaho.commons.connection.IPentahoResultSet;
import org.pentaho.core.runtime.IRuntimeContext;
import org.pentaho.core.services.BaseRequestHandler;
import org.pentaho.core.session.IPentahoSession;
import org.pentaho.core.solution.ActionResource;
import org.pentaho.core.solution.HttpRequestParameterProvider;
import org.pentaho.core.solution.IActionResource;
import org.pentaho.core.solution.IParameterProvider;
import org.pentaho.core.solution.SimpleOutputHandler;
import org.pentaho.core.system.PentahoSystem;
import org.pentaho.core.ui.SimpleUrlFactory;
import org.pentaho.core.util.TemplateUtil;
import org.pentaho.core.util.UIUtil;
import org.pentaho.data.connection.sql.SQLConnection;
import org.pentaho.messages.Messages;
import org.pentaho.messages.util.LocaleHelper;
import org.pentaho.plugin.jfreechart.ChartDefinition;
import org.pentaho.plugin.jfreechart.JFreeChartEngine;
import org.pentaho.ui.component.DashboardWidgetComponent;
import org.pentaho.ui.component.charting.AbstractChartComponent;
import org.pentaho.ui.component.charting.AbstractJFreeChartComponent;
import org.pentaho.ui.component.charting.CategoryDatasetChartComponent;
import org.pentaho.ui.component.charting.DialChartComponent;
import org.pentaho.ui.component.charting.PieDatasetChartComponent;
import org.pentaho.ui.component.charting.TimeSeriesCollectionChartComponent;
import org.pentaho.ui.component.charting.XYSeriesCollectionChartComponent;
import org.pentaho.ui.component.charting.XYZSeriesCollectionChartComponent;
import org.pentaho.util.logging.ILogger;
/**
* This class provides wrapper functions to make it easier to execute action
* sequences and generate a widget.
*/
public class ChartHelper {
/**
* doChart generates the images and html necessary to render various charts within a web page.
*
* @param solutionName the solution name
* @param actionPath the action path
* @param chartName the xml file describing the chart
* @param parameterProvider the collection of parameters to customize the chart
* @param outputStream the output string buffer for the content
* @param userSession the user session object
* @param messages a collection to store error and logging messages
* @param logger logging object
*
* @return true if successful
*/
public static boolean doChart(String solutionName, String actionPath, String chartName,
IParameterProvider parameterProvider, StringBuffer outputStream, IPentahoSession userSession, ArrayList messages,
ILogger logger) {
boolean result = true;
String content = null;
StringBuffer messageBuffer = new StringBuffer();
if (logger == null) {
// No logger? The usersession extends ILogger, use it for logging
logger = userSession;
}
// Retrieve all parameters from parameter provider
String outerParams = parameterProvider.getStringParameter("outer-params", null); //$NON-NLS-1$
String innerParam = parameterProvider.getStringParameter("inner-param", null); //$NON-NLS-1$
String urlDrillTemplate = parameterProvider.getStringParameter("drill-url", null); //$NON-NLS-1$
String imageUrl = parameterProvider.getStringParameter("image-url", null); //$NON-NLS-1$
// Very likely null; allow API users to continue to pass the dial value via parameters
String dialValue = parameterProvider.getStringParameter("value", null); //$NON-NLS-1$
if (imageUrl == null) {
imageUrl = PentahoSystem.getApplicationContext().getBaseUrl();
}
if (urlDrillTemplate == null) {
urlDrillTemplate = ""; //$NON-NLS-1$
}
int width = (int) parameterProvider.getLongParameter("image-width", 150); //$NON-NLS-1$
int height = (int) parameterProvider.getLongParameter("image-height", 150); //$NON-NLS-1$
SimpleUrlFactory urlFactory = new SimpleUrlFactory(urlDrillTemplate);
// Determine the type of chart we are building; these values can come from the chart xml definition, or
// from the parameter provider. Try the parameter provider first, for performance reasons.
String chartTypeStr = parameterProvider.getStringParameter(ChartDefinition.TYPE_NODE_NAME, null);
String datasetType = ChartDefinition.CATAGORY_DATASET_STR;
String definitionPath = solutionName + File.separator + actionPath + File.separator + chartName;
if ((chartTypeStr == null) || (chartTypeStr.length() == 0)) {
// load the XML document that defines the chart
ActionResource resource = new ActionResource(chartName, IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", //$NON-NLS-1$
definitionPath);
try {
// attempt to get the chart type and possibly data type from the xml doc
Document chartDefinition = AbstractJFreeChartComponent.getResourceAsDocument(userSession, resource);
Node chartAttributes = chartDefinition.selectSingleNode("//" + AbstractChartComponent.CHART_NODE_NAME); //$NON-NLS-1$
chartTypeStr = chartAttributes.selectSingleNode(ChartDefinition.TYPE_NODE_NAME).getText();
Node datasetTypeNode = chartAttributes.selectSingleNode(ChartDefinition.DATASET_TYPE_NODE_NAME);
if (datasetTypeNode != null) {
datasetType = datasetTypeNode.getText();
}
} catch (Exception e) {
logger.error(Messages.getErrorString("ChartHelper.ERROR_0001_IO_PROBLEM_GETTING_CHART_TYPE"), e); //$NON-NLS-1$
UIUtil
.formatErrorMessage(
"text/html", Messages.getString("ChartHelper.ERROR_0001_IO_PROBLEM_GETTING_CHART_TYPE"), messages, messageBuffer); //$NON-NLS-1$ //$NON-NLS-2$
content = messageBuffer.toString();
result = false;
}
}
// Check again - do we have a chart type now? If not, bail out, we have no idea what to try to generate
if ((chartTypeStr == null) || (chartTypeStr.length() == 0)) {
logger.error(Messages.getString("ChartHelper.ERROR_0002_COULD_NOT_DETERMINE_CHART_TYPE")); //$NON-NLS-1$
UIUtil
.formatErrorMessage(
"text/html", Messages.getString("ChartHelper.ERROR_0002_COULD_NOT_DETERMINE_CHART_TYPE"), messages, messageBuffer); //$NON-NLS-1$ //$NON-NLS-2$
content = messageBuffer.toString();
result = false;
}
if (!result) {
outputStream.append(content);
return result;
}
int chartType = JFreeChartEngine.getChartType(chartTypeStr);
AbstractJFreeChartComponent chartComponent = null;
try {
// Some charts are determined by the dataset that is passed in; check these first...
if (datasetType.equalsIgnoreCase(ChartDefinition.TIME_SERIES_COLLECTION_STR)) {
chartComponent = new TimeSeriesCollectionChartComponent(chartType, definitionPath, width, height, urlFactory,
messages);
} else if (datasetType.equalsIgnoreCase(ChartDefinition.XY_SERIES_COLLECTION_STR)) {
chartComponent = new XYSeriesCollectionChartComponent(chartType, definitionPath, width, height, urlFactory,
messages);
} else if (datasetType.equalsIgnoreCase(ChartDefinition.XYZ_SERIES_COLLECTION_STR)) {
chartComponent = new XYZSeriesCollectionChartComponent(chartType, definitionPath, width, height, urlFactory,
messages);
}
// Didn't find a dataset, so try to create the component based on chart type.
if (chartComponent == null) {
switch (chartType) {
case JFreeChartEngine.BAR_CHART_TYPE:
case JFreeChartEngine.AREA_CHART_TYPE:
case JFreeChartEngine.BAR_LINE_CHART_TYPE:
case JFreeChartEngine.LINE_CHART_TYPE:
case JFreeChartEngine.DIFFERENCE_CHART_TYPE:
case JFreeChartEngine.DOT_CHART_TYPE:
case JFreeChartEngine.STEP_AREA_CHART_TYPE:
case JFreeChartEngine.STEP_CHART_TYPE:
case JFreeChartEngine.PIE_GRID_CHART_TYPE:
chartComponent = new CategoryDatasetChartComponent(chartType, definitionPath, width, height, urlFactory,
messages);
break;
case JFreeChartEngine.PIE_CHART_TYPE:
chartComponent = new PieDatasetChartComponent(chartType, definitionPath, width, height, urlFactory,
messages);
break;
case JFreeChartEngine.DIAL_CHART_TYPE:
chartComponent = new DialChartComponent(chartType, definitionPath, width, height, urlFactory, messages);
if (dialValue != null) {
Number numericDialValue = DataUtilities.toNumber(dialValue, LocaleHelper
.getCurrencyFormat(), LocaleHelper.getNumberFormat());
((DialChartComponent) chartComponent).setValue(numericDialValue.doubleValue());
}
break;
case JFreeChartEngine.BUBBLE_CHART_TYPE:
chartComponent = new XYZSeriesCollectionChartComponent(chartType, definitionPath, width, height,
urlFactory, messages);
break;
case JFreeChartEngine.UNDEFINED_CHART_TYPE:
default:
// Unsupported chart type, bail out
logger.error(Messages.getString(
"ChartHelper.ERROR_0003_INVALID_CHART_TYPE", chartTypeStr, Integer.toString(chartType))); //$NON-NLS-1$
UIUtil.formatErrorMessage("text/html", Messages.getString("ChartHelper.ERROR_0003_INVALID_CHART_TYPE", //$NON-NLS-1$ //$NON-NLS-2$
chartTypeStr, Integer.toString(chartType)), messages, messageBuffer);
content = messageBuffer.toString();
result = false;
}
}
if (result && (chartComponent != null)) {
try {
chartComponent.setLoggingLevel(logger.getLoggingLevel());
chartComponent.validate(userSession, null);
chartComponent.setDataAction(definitionPath);
chartComponent.setUrlTemplate(urlDrillTemplate);
String seriesName = parameterProvider.getStringParameter("series-name", null); //$NON-NLS-1$
if (chartComponent instanceof CategoryDatasetChartComponent) {
((CategoryDatasetChartComponent) chartComponent).setSeriesName(seriesName);
}
// WARNING!!! This is an atypical way to access data for the chart... these parameters and their
// usage are undocumented, and only left in here to support older solutions that may be using them.
// *************** START QUESTIONABLE CODE ********************************************************
String connectionName = parameterProvider.getStringParameter("connection", null); //$NON-NLS-1$
String query = parameterProvider.getStringParameter("query", null); //$NON-NLS-1$
String dataAction = parameterProvider.getStringParameter("data-process", null); //$NON-NLS-1$
IPentahoConnection connection = null;
try {
chartComponent.setParamName(innerParam);
chartComponent.setParameterProvider(HttpRequestParameterProvider.SCOPE_REQUEST, parameterProvider);
if (connectionName != null && query != null) {
connection = new SQLConnection(connectionName, logger);
try {
query = TemplateUtil.applyTemplate(query, TemplateUtil.parametersToProperties(parameterProvider), null);
IPentahoResultSet results = connection.executeQuery(query);
chartComponent.setValues(results);
} finally {
}
chartComponent.setUrlTemplate(urlDrillTemplate);
if (outerParams != null) {
StringTokenizer tokenizer = new StringTokenizer(outerParams, ";"); //$NON-NLS-1$
while (tokenizer.hasMoreTokens()) {
chartComponent.addOuterParamName(tokenizer.nextToken());
}
}
} else if (dataAction != null) {
PentahoSystem.ActionInfo actionInfo = PentahoSystem.parseActionString(dataAction);
if (actionInfo != null) {
chartComponent.setDataAction(actionInfo.getSolutionName(), actionInfo.getPath(), actionInfo
.getActionName(), "rule-result"); //$NON-NLS-1$
}
}
// ***************** END QUESTIONABLE CODE ********************************************************
content = chartComponent.getContent("text/html"); //$NON-NLS-1$
} finally {
if (connection != null) {
connection.close();
}
}
} catch (Throwable e) {
logger.error(Messages.getErrorString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), e); //$NON-NLS-1$
}
} // end of if(result)
try {
if (content == null) {
UIUtil
.formatErrorMessage(
"text/html", Messages.getErrorString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), messages, messageBuffer); //$NON-NLS-1$ //$NON-NLS-2$
content = messageBuffer.toString();
result = false;
}
outputStream.append(content);
} catch (Exception e) {
logger.error(Messages.getErrorString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), e); //$NON-NLS-1$
}
} finally {
if (chartComponent != null)
chartComponent.dispose();
}
return result;
}
/**
* doPieChart generates the images and html necessary to render pie charts.
* It provides a simple wrapper around the class
* org.pentaho.ui.component.charting.PieDatasetChartComponent
*
* @param solutionName the solution name
* @param actionPath the action path
* @param chartName the xml file describing the chart
* @param parameterProvider the collection of parameters to customize the chart
* @param outputStream the output string buffer for the content
* @param userSession the user session object
* @param messages a collection to store error and logging messages
* @param logger logging object
*
* @return true if successful
* @deprecated use doChart instead
*/
public static boolean doPieChart(String solutionName, String actionPath, String chartName,
IParameterProvider parameterProvider, StringBuffer outputStream, IPentahoSession userSession, ArrayList messages,
ILogger logger) {
boolean result = true;
String outerParams = parameterProvider.getStringParameter("outer-params", null); //$NON-NLS-1$
String innerParam = parameterProvider.getStringParameter("inner-param", null); //$NON-NLS-1$
String urlDrillTemplate = parameterProvider.getStringParameter("drill-url", null); //$NON-NLS-1$
String imageUrl = parameterProvider.getStringParameter("image-url", null); //$NON-NLS-1$
if (imageUrl == null) {
imageUrl = PentahoSystem.getApplicationContext().getBaseUrl();
}
if (urlDrillTemplate == null) {
urlDrillTemplate = ""; //$NON-NLS-1$
}
int width = (int) parameterProvider.getLongParameter("image-width", 150); //$NON-NLS-1$
int height = (int) parameterProvider.getLongParameter("image-height", 150); //$NON-NLS-1$
SimpleUrlFactory urlFactory = new SimpleUrlFactory(urlDrillTemplate);
PieDatasetChartComponent chartComponent = null;
try {
String chartDefinitionStr = solutionName + File.separator + actionPath + File.separator + chartName;
chartComponent = new PieDatasetChartComponent(JFreeChartEngine.PIE_CHART_TYPE, chartDefinitionStr, width, height,
urlFactory, messages);
if (logger != null) {
chartComponent.setLoggingLevel(logger.getLoggingLevel());
}
chartComponent.validate(userSession, null);
chartComponent.setUrlTemplate(urlDrillTemplate);
if (outerParams != null) {
StringTokenizer tokenizer = new StringTokenizer(outerParams, ";"); //$NON-NLS-1$
while (tokenizer.hasMoreTokens()) {
chartComponent.addOuterParamName(tokenizer.nextToken());
}
}
chartComponent.setParamName(innerParam);
chartComponent.setDataAction(chartDefinitionStr);
chartComponent.setParameterProvider(HttpRequestParameterProvider.SCOPE_REQUEST, parameterProvider);
String content = chartComponent.getContent("text/html"); //$NON-NLS-1$
if (content == null || content.equals("")) { //$NON-NLS-1$
content = " "; //$NON-NLS-1$
}
if (content == null) {
StringBuffer buffer = new StringBuffer();
UIUtil.formatErrorMessage(
"text/html", Messages.getString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), messages, buffer); //$NON-NLS-1$ //$NON-NLS-2$
content = buffer.toString();
result = false;
}
outputStream.append(content);
} finally {
if (chartComponent != null)
chartComponent.dispose();
}
return result;
}
/**
* doDial generates the images and html necessary to render dials. It
* provides a simple wrapper around the class
* org.pentaho.ui.component.DashboardWidgetComponent
*
* @param solutionName the solution name
* @param actionPath the action path
* @param chartName the xml file describing the chart
* @param parameterProvider the collection of parameters to customize the chart
* @param outputStream the output string buffer for the content
* @param userSession the user session object
* @param messages a collection to store error and logging messages
* @param logger logging object
*
* @return true if successful
* @deprecated use doChart() instead
*/
public static boolean doDial(String solutionName, String actionPath, String chartName,
IParameterProvider parameterProvider, StringBuffer outputStream, IPentahoSession userSession, ArrayList messages,
ILogger logger) {
boolean result = true;
String linkUrl = parameterProvider.getStringParameter("drill-url", null); //$NON-NLS-1$
String imageUrl = parameterProvider.getStringParameter("image-url", null); //$NON-NLS-1$
if (imageUrl == null) {
imageUrl = PentahoSystem.getApplicationContext().getBaseUrl();
}
if (linkUrl == null) {
linkUrl = ""; //$NON-NLS-1$
}
int width = (int) parameterProvider.getLongParameter("image-width", 150); //$NON-NLS-1$
int height = (int) parameterProvider.getLongParameter("image-height", 150); //$NON-NLS-1$
SimpleUrlFactory urlFactory = new SimpleUrlFactory(linkUrl);
DashboardWidgetComponent widget = null;
try {
widget = new DashboardWidgetComponent(DashboardWidgetComponent.TYPE_DIAL, solutionName + File.separator
+ actionPath + File.separator + chartName, width, height, urlFactory, messages);
if (logger != null) {
widget.setLoggingLevel(logger.getLoggingLevel());
}
widget.validate(userSession, null);
widget.setParameterProvider(HttpRequestParameterProvider.SCOPE_REQUEST, parameterProvider);
String value = parameterProvider.getStringParameter("value", "0"); //$NON-NLS-1$//$NON-NLS-2$
Number numericValue = DataUtilities.toNumber(value, LocaleHelper.getCurrencyFormat(), LocaleHelper.getNumberFormat());
widget.setValue(numericValue.doubleValue());
String title = parameterProvider.getStringParameter("title", ""); //$NON-NLS-1$ //$NON-NLS-2$
widget.setTitle(title);
String content = widget.getContent("text/html"); //$NON-NLS-1$
if (content == null) {
StringBuffer buffer = new StringBuffer();
UIUtil.formatErrorMessage(
"text/html", Messages.getString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), messages, buffer); //$NON-NLS-1$ //$NON-NLS-2$
content = buffer.toString();
result = false;
}
if (content == null || content.equals("")) { //$NON-NLS-1$
content = " "; //$NON-NLS-1$
}
outputStream.append(content);
} finally {
if (widget != null)
widget.dispose();
}
return result;
}
/**
* doAction executes an action within the bi platform and returns true if successful.
*
* @param solutionName the solution name
* @param actionPath the action path
* @param actionName the action name
* @param processId the process id
* @param parameterProvider the collection of parameters to customize the chart
* @param userSession the user session object
* @param messages a collection to store error and logging messages
* @param logger logging object
*
* @return the runtime context
*/
public static boolean doAction(String solutionName, String actionPath, String actionName, String processId,
IParameterProvider parameterProvider, OutputStream outputStream, IPentahoSession userSession, ArrayList messages,
ILogger logger) {
SimpleOutputHandler outputHandler = new SimpleOutputHandler(outputStream, false);
BaseRequestHandler requestHandler = new BaseRequestHandler(userSession, null, outputHandler, parameterProvider,
null);
requestHandler.setProcessId(processId);
requestHandler.setAction(actionPath, actionName);
requestHandler.setSolutionName(solutionName);
IRuntimeContext runtime = null;
int status = IRuntimeContext.RUNTIME_STATUS_FAILURE;
try {
runtime = requestHandler.handleActionRequest(0, 0);
if (runtime != null) {
status = runtime.getStatus();
}
} finally {
if (runtime != null) {
runtime.dispose();
}
}
return status == IRuntimeContext.RUNTIME_STATUS_SUCCESS;
}
/**
* doAction executes an action within the bi platform and returns the runtime context.
*
* @param solutionName the solution name
* @param actionPath the action path
* @param actionName the action name
* @param processId the process id
* @param parameterProvider the collection of parameters to customize the chart
* @param userSession the user session object
* @param messages a collection to store error and logging messages
* @param logger logging object
*
* @return the runtime context
*/
public static IRuntimeContext doAction(String solutionName, String actionPath, String actionName, String processId,
IParameterProvider parameterProvider, IPentahoSession userSession, ArrayList messages, ILogger logger) {
SimpleOutputHandler outputHandler = new SimpleOutputHandler((OutputStream) null, false);
BaseRequestHandler requestHandler = new BaseRequestHandler(userSession, null, outputHandler, parameterProvider,
null);
requestHandler.setProcessId(processId);
requestHandler.setAction(actionPath, actionName);
requestHandler.setSolutionName(solutionName);
IRuntimeContext runtime = null;
try {
runtime = requestHandler.handleActionRequest(0, 0);
} catch (Throwable t) {
}
return runtime;
}
}
The table below shows all metrics for ChartHelper.java.




