/*!
* This program 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.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.extensions.drilldown;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.table.DefaultTableModel;
import org.pentaho.reporting.engine.classic.core.DataRow;
import org.pentaho.reporting.engine.classic.core.StaticDataRow;
import org.pentaho.reporting.engine.classic.core.function.ExpressionRuntime;
import org.pentaho.reporting.engine.classic.core.function.GenericExpressionRuntime;
import org.pentaho.reporting.engine.classic.core.function.ReportFormulaContext;
import org.pentaho.reporting.engine.classic.core.function.WrapperExpressionRuntime;
import org.pentaho.reporting.engine.classic.core.layout.output.DefaultProcessingContext;
import org.pentaho.reporting.engine.classic.core.parameters.CompoundDataRow;
import org.pentaho.reporting.engine.classic.core.util.beans.BeanException;
import org.pentaho.reporting.libraries.formula.ErrorValue;
import org.pentaho.reporting.libraries.formula.EvaluationException;
import org.pentaho.reporting.libraries.formula.Formula;
import org.pentaho.reporting.libraries.formula.FormulaContext;
import org.pentaho.reporting.libraries.formula.LibFormulaErrorValue;
import org.pentaho.reporting.libraries.formula.parser.ParseException;
public class FormulaLinkCustomizer implements LinkCustomizer
{
private static final String TAB_ACTIVE_PARAMETER = "::TabActive";
private static final String TAB_NAME_PARAMETER = "::TabName";
public FormulaLinkCustomizer()
{
}
private String computeMantleTabActive(final FormulaContext formulaContext,
final ParameterEntry[] entries) throws EvaluationException
{
for (int i = 0; i < entries.length; i++)
{
final ParameterEntry parameterEntry = entries[i];
final String parameterName = parameterEntry.getParameterName();
if (TAB_ACTIVE_PARAMETER.equals(parameterName))
{
final Object o = parameterEntry.getParameterValue();
if (o != null)
{
return String.valueOf(o);
}
}
}
final Object o = formulaContext.resolveReference(TAB_ACTIVE_PARAMETER);
if (o != null)
{
return String.valueOf(o);
}
return null;
}
private String computeMantleTabName(final FormulaContext formulaContext,
final ParameterEntry[] entries) throws EvaluationException
{
for (int i = 0; i < entries.length; i++)
{
final ParameterEntry parameterEntry = entries[i];
final String parameterName = parameterEntry.getParameterName();
if (TAB_NAME_PARAMETER.equals(parameterName))
{
final Object o = parameterEntry.getParameterValue();
if (o != null)
{
return String.valueOf(o);
}
}
}
final Object o = formulaContext.resolveReference(TAB_NAME_PARAMETER);
if (o != null)
{
return String.valueOf(o);
}
return null;
}
private ParameterEntry[] filterEntries(final ParameterEntry[] entries)
{
final ArrayList<ParameterEntry> list = new ArrayList<ParameterEntry>();
for (int i = 0; i < entries.length; i++)
{
final ParameterEntry entry = entries[i];
if (isFiltered(entry))
{
continue;
}
list.add(entry);
}
return list.toArray(new ParameterEntry[list.size()]);
}
protected boolean isFiltered(final ParameterEntry entry)
{
if (TAB_NAME_PARAMETER.equals(entry.getParameterName()))
{
return true;
}
if (TAB_ACTIVE_PARAMETER.equals(entry.getParameterName()))
{
return true;
}
return false;
}
private Object[][] createEntryTable(final ParameterEntry[] entries)
{
final Object[][] values = new Object[entries.length][2];
for (int i = 0; i < entries.length; i++)
{
final ParameterEntry entry = entries[i];
values[i][0] = (entry.getParameterName());
values[i][1] = (entry.getParameterValue());
}
return values;
}
public String format(final FormulaContext formulaContext,
final String configIndicator,
final String reportPath,
final ParameterEntry[] entries) throws EvaluationException
{
try
{
final Map<String, Object> parameterValues =
createParameterMap(formulaContext, configIndicator, reportPath, entries);
final StaticDataRow staticDataRow = new StaticDataRow(parameterValues);
final ExpressionRuntime expressionRuntime;
if (formulaContext instanceof ReportFormulaContext)
{
final ReportFormulaContext rfc = (ReportFormulaContext) formulaContext;
expressionRuntime = new WrapperExpressionRuntime(staticDataRow, rfc.getRuntime());
}
else
{
expressionRuntime = new GenericExpressionRuntime
(new CompoundDataRow(staticDataRow, createDataRow(entries)),
new DefaultTableModel(), -1, new DefaultProcessingContext());
}
final String formula = computeFormula(configIndicator);
final Formula compiledFormula = new Formula(formula);
compiledFormula.initialize(new ReportFormulaContext(formulaContext, expressionRuntime));
final Object o = compiledFormula.evaluate();
if (o instanceof ErrorValue)
{
throw EvaluationException.getInstance((ErrorValue) o);
}
if (o == null)
{
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_NA_VALUE);
}
return String.valueOf(o);
}
catch (final UnsupportedEncodingException e)
{
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
}
catch (final BeanException e)
{
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
}
catch (ParseException e)
{
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
}
catch (EvaluationException e)
{
throw e;
}
catch (Exception e)
{
e.printStackTrace();
throw EvaluationException.getInstance(LibFormulaErrorValue.ERROR_UNEXPECTED_VALUE);
}
}
protected Map<String, Object> createParameterMap(final FormulaContext formulaContext,
final String configIndicator,
final String reportPath,
final ParameterEntry[] entries)
throws UnsupportedEncodingException, BeanException, EvaluationException
{
final String parameter = PatternLinkCustomizer.computeParameter(formulaContext, filterEntries(entries));
final HashMap<String, Object> parameterValues = new HashMap<String, Object>();
if (reportPath == null || reportPath.endsWith("/")) {
parameterValues.put("::path", reportPath);
} else {
// make sure the path ends in slash for consistency
parameterValues.put("::path", reportPath + "/");
}
parameterValues.put("::parameter", parameter);
parameterValues.put("::config", configIndicator);
parameterValues.put("::entries", createEntryTable(entries));
parameterValues.put(TAB_NAME_PARAMETER, computeMantleTabName(formulaContext, entries));
parameterValues.put(TAB_ACTIVE_PARAMETER, computeMantleTabActive(formulaContext, entries));
return parameterValues;
}
private String computeFormula(final String configIndicator) throws EvaluationException
{
final DrillDownProfile downProfile = DrillDownProfileMetaData.getInstance().getDrillDownProfile(configIndicator);
return downProfile.getAttribute("formula");
}
private DataRow createDataRow(final ParameterEntry[] parameterEntries)
{
final String[] parameterNames = new String[parameterEntries.length];
final Object[] parameterValues = new Object[parameterEntries.length];
for (int i = 0; i < parameterEntries.length; i++)
{
final ParameterEntry entry = parameterEntries[i];
parameterNames[i] = entry.getParameterName();
parameterValues[i] = entry.getParameterValue();
}
return new StaticDataRow(parameterNames, parameterValues);
}
}