Java tutorial
/*! * * 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 (c) 2002-2018 Hitachi Vantara. All rights reserved. * */ package org.pentaho.platform.uifoundation.chart; import org.apache.commons.lang.StringUtils; 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.platform.api.engine.ILogger; import org.pentaho.platform.api.engine.IMessageFormatter; import org.pentaho.platform.api.engine.IParameterProvider; import org.pentaho.platform.api.engine.IPentahoRequestContext; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission; import org.pentaho.platform.engine.core.system.PentahoRequestContextHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.ActionSequenceJCRHelper; import org.pentaho.platform.engine.services.connection.PentahoConnectionFactory; import org.pentaho.platform.engine.services.runtime.TemplateUtil; import org.pentaho.platform.uifoundation.messages.Messages; import org.pentaho.platform.util.logging.Logger; import org.pentaho.platform.util.messages.LocaleHelper; import org.pentaho.platform.util.messages.MessagesBase; import org.pentaho.platform.util.web.SimpleUrlFactory; import java.io.File; import java.util.ArrayList; import java.util.StringTokenizer; /** * This class provides wrapper functions to make it easier to execute action sequences and generate a widget. */ @Deprecated // BISERVER-12899 public class ChartHelper { private static void deprecateWarning() { String key = "PentahoSystem.WARN_DEPRECATED_CLASS"; //$NON-NLS-1$ MessagesBase messages = org.pentaho.platform.engine.core.messages.Messages.getInstance(); String message = messages.getErrorString(key, ChartHelper.class.getCanonicalName()); String stackTrace = StringUtils.join(Thread.currentThread().getStackTrace(), "\n\t"); //$NON-NLS-1$ Logger.warn(ChartHelper.class, message + "\n\t" + stackTrace); //$NON-NLS-1$ } /** * doChart generates the images and html necessary to render various charts within a web page. * * @param actionPath * full path including the name of the action sequence or resource * @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 public static boolean doChart(final String actionPath, final IParameterProvider parameterProvider, final StringBuffer outputStream, final IPentahoSession userSession, final ArrayList messages, ILogger logger) { deprecateWarning(); 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$ IPentahoRequestContext requestContext = PentahoRequestContextHolder.getRequestContext(); if (imageUrl == null) { imageUrl = requestContext.getContextPath(); //$NON-NLS-1$ } 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.CATEGORY_DATASET_STR; if ((chartTypeStr == null) || (chartTypeStr.length() == 0)) { try { // attempt to get the chart type and possibly data type from the xml doc ActionSequenceJCRHelper jcrHelper = new ActionSequenceJCRHelper(userSession); Document chartDefinition = jcrHelper.getSolutionDocument(actionPath, RepositoryFilePermission.READ); 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.getInstance() .getErrorString("ChartHelper.ERROR_0001_IO_PROBLEM_GETTING_CHART_TYPE"), e); //$NON-NLS-1$ PentahoSystem.get(IMessageFormatter.class, userSession).formatErrorMessage("text/html", //$NON-NLS-1$ Messages.getInstance().getString("ChartHelper.ERROR_0001_IO_PROBLEM_GETTING_CHART_TYPE"), //$NON-NLS-1$ messages, messageBuffer); 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.getInstance().getString("ChartHelper.ERROR_0002_COULD_NOT_DETERMINE_CHART_TYPE")); //$NON-NLS-1$ PentahoSystem.get(IMessageFormatter.class, userSession).formatErrorMessage("text/html", //$NON-NLS-1$ Messages.getInstance().getString("ChartHelper.ERROR_0002_COULD_NOT_DETERMINE_CHART_TYPE"), //$NON-NLS-1$ messages, messageBuffer); 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, actionPath, width, height, urlFactory, messages); } else if (datasetType.equalsIgnoreCase(ChartDefinition.XY_SERIES_COLLECTION_STR)) { chartComponent = new XYSeriesCollectionChartComponent(chartType, actionPath, width, height, urlFactory, messages); } else if (datasetType.equalsIgnoreCase(ChartDefinition.XYZ_SERIES_COLLECTION_STR)) { chartComponent = new XYZSeriesCollectionChartComponent(chartType, actionPath, 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, actionPath, width, height, urlFactory, messages); break; case JFreeChartEngine.PIE_CHART_TYPE: chartComponent = new PieDatasetChartComponent(chartType, actionPath, width, height, urlFactory, messages); break; case JFreeChartEngine.DIAL_CHART_TYPE: chartComponent = new DialChartComponent(chartType, actionPath, 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, actionPath, width, height, urlFactory, messages); break; case JFreeChartEngine.UNDEFINED_CHART_TYPE: default: // Unsupported chart type, bail out logger.error(Messages.getInstance().getString("ChartHelper.ERROR_0003_INVALID_CHART_TYPE", //$NON-NLS-1$ chartTypeStr, Integer.toString(chartType))); PentahoSystem.get(IMessageFormatter.class, userSession).formatErrorMessage("text/html", //$NON-NLS-1$ Messages.getInstance().getString("ChartHelper.ERROR_0003_INVALID_CHART_TYPE", //$NON-NLS-1$ 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(actionPath); 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(IParameterProvider.SCOPE_REQUEST, parameterProvider); if ((connectionName != null) && (query != null)) { // connection = new SQLConnection(connectionName, logger) // TODO support non-SQL data sources. Much easier now using the factory connection = PentahoConnectionFactory.getConnection(IPentahoConnection.SQL_DATASOURCE, connectionName, userSession, logger); try { query = TemplateUtil.applyTemplate(query, TemplateUtil.parametersToProperties(parameterProvider), null); IPentahoResultSet results = connection.executeQuery(query); chartComponent.setValues(results); } finally { boolean ignored = true; } 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) { chartComponent.setDataAction(dataAction); } // ***************** END QUESTIONABLE CODE ******************************************************** content = chartComponent.getContent("text/html"); //$NON-NLS-1$ } finally { if (connection != null) { connection.close(); } } } catch (Throwable e) { logger.error(Messages.getInstance().getErrorString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), //$NON-NLS-1$ e); } } // end of if(result) try { if (content == null) { PentahoSystem.get(IMessageFormatter.class, userSession).formatErrorMessage("text/html", //$NON-NLS-1$ Messages.getInstance().getErrorString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), //$NON-NLS-1$ messages, messageBuffer); content = messageBuffer.toString(); result = false; } outputStream.append(content); } catch (Exception e) { logger.error(Messages.getInstance().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 */ @Deprecated public static boolean doPieChart(final String actionPath, final IParameterProvider parameterProvider, final StringBuffer outputStream, final IPentahoSession userSession, final ArrayList messages, final ILogger logger) { deprecateWarning(); 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$ IPentahoRequestContext requestContext = PentahoRequestContextHolder.getRequestContext(); if (imageUrl == null) { imageUrl = requestContext.getContextPath(); //$NON-NLS-1$ } 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 { chartComponent = new PieDatasetChartComponent(JFreeChartEngine.PIE_CHART_TYPE, actionPath, 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(actionPath); chartComponent.setParameterProvider(IParameterProvider.SCOPE_REQUEST, parameterProvider); String content = chartComponent.getContent("text/html"); //$NON-NLS-1$ if ((content == null) || content.equals("")) { //$NON-NLS-1$ content = " "; //$NON-NLS-1$ } 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 */ @Deprecated public static boolean doDial(final String solutionName, final String actionPath, final String chartName, final IParameterProvider parameterProvider, final StringBuffer outputStream, final IPentahoSession userSession, final ArrayList messages, final ILogger logger) { deprecateWarning(); boolean result = true; String linkUrl = parameterProvider.getStringParameter("drill-url", null); //$NON-NLS-1$ String imageUrl = parameterProvider.getStringParameter("image-url", null); //$NON-NLS-1$ IPentahoRequestContext requestContext = PentahoRequestContextHolder.getRequestContext(); if (imageUrl == null) { imageUrl = requestContext.getContextPath(); //$NON-NLS-1$ } 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(IParameterProvider.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(); PentahoSystem.get(IMessageFormatter.class, userSession).formatErrorMessage("text/html", //$NON-NLS-1$ Messages.getInstance().getString("Widget.ERROR_0001_COULD_NOT_CREATE_WIDGET"), messages, //$NON-NLS-1$ buffer); 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; } }