/projects/jasperreports-3.7.4/src/net/sf/jasperreports/compilers/JavaScriptEvaluator.java
Java | 347 lines | 262 code | 39 blank | 46 comment | 13 complexity | 65f26bb657fc93a1840f9326fc0bb0fe MD5 | raw file
- /*
- * JasperReports - Free Java Reporting Library.
- * Copyright (C) 2001 - 2009 Jaspersoft Corporation. All rights reserved.
- * http://www.jaspersoft.com
- *
- * Unless you have purchased a commercial license agreement from Jaspersoft,
- * the following license terms apply:
- *
- * This program is part of JasperReports.
- *
- * JasperReports 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 3 of the License, or
- * (at your option) any later version.
- *
- * JasperReports 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 JasperReports. If not, see <http://www.gnu.org/licenses/>.
- */
- package net.sf.jasperreports.compilers;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.Map;
- import net.sf.jasperreports.engine.JRException;
- import net.sf.jasperreports.engine.JRExpression;
- import net.sf.jasperreports.engine.JRExpressionChunk;
- import net.sf.jasperreports.engine.JRRuntimeException;
- import net.sf.jasperreports.engine.fill.JREvaluator;
- import net.sf.jasperreports.engine.fill.JRFillField;
- import net.sf.jasperreports.engine.fill.JRFillParameter;
- import net.sf.jasperreports.engine.fill.JRFillVariable;
- import net.sf.jasperreports.engine.util.JRClassLoader;
- import net.sf.jasperreports.engine.util.JRStringUtil;
- import org.mozilla.javascript.Context;
- import org.mozilla.javascript.ContextFactory;
- import org.mozilla.javascript.EvaluatorException;
- import org.mozilla.javascript.Script;
- import org.mozilla.javascript.ScriptableObject;
- /**
- * JavaScript expression evaluator.
- *
- * @author Lucian Chirita (lucianc@users.sourceforge.net)
- * @version $Id: JavaScriptEvaluator.java 3717 2010-04-09 10:01:33Z teodord $
- */
- public class JavaScriptEvaluator extends JREvaluator
- {
-
- /**
- * Base JavaScript value class.
- */
- public abstract static class JSValue
- {
- private final ScriptableObject scope;
- protected JSValue(ScriptableObject scope)
- {
- this.scope = scope;
- }
-
- protected final Object toJSValue(Object value)
- {
- return Context.javaToJS(value, scope);
- }
- }
-
- /**
- * Parameter class used in JavaScript expressions.
- */
- public static class JSParameter extends JSValue
- {
- private final JRFillParameter parameter;
-
- public JSParameter(JRFillParameter parameter, ScriptableObject scope)
- {
- super(scope);
- this.parameter = parameter;
- }
-
- public Object getValue()
- {
- return toJSValue(parameter.getValue());
- }
- }
-
- /**
- * Field class used in JavaScript expressions.
- */
- public static class JSField extends JSValue
- {
- private final JRFillField field;
-
- public JSField(JRFillField field, ScriptableObject scope)
- {
- super(scope);
- this.field = field;
- }
-
- public Object getValue()
- {
- return toJSValue(field.getValue());
- }
-
- public Object getOldValue()
- {
- return toJSValue(field.getOldValue());
- }
- }
-
- /**
- * Variable class used in JavaScript expressions.
- */
- public static class JSVariable extends JSValue
- {
- private final JRFillVariable variable;
-
- public JSVariable(JRFillVariable variable, ScriptableObject scope)
- {
- super(scope);
- this.variable = variable;
- }
-
- public Object getValue()
- {
- return toJSValue(variable.getValue());
- }
-
- public Object getOldValue()
- {
- return toJSValue(variable.getOldValue());
- }
-
- public Object getEstimatedValue()
- {
- return toJSValue(variable.getEstimatedValue());
- }
- }
-
- protected static JavaScriptCompileData.Expression createJSExpression(JRExpression expression)
- {
- StringBuffer defaultExpr = new StringBuffer();
- StringBuffer oldExpr = new StringBuffer();
- StringBuffer estimatedExpr = new StringBuffer();
-
- JRExpressionChunk[] chunks = expression.getChunks();
- if (chunks == null)
- {
- defaultExpr.append("null");
- oldExpr.append("null");
- estimatedExpr.append("null");
- }
- else
- {
- for (int i = 0; i < chunks.length; i++)
- {
- JRExpressionChunk chunk = chunks[i];
- switch (chunk.getType())
- {
- case JRExpressionChunk.TYPE_TEXT:
- defaultExpr.append(chunk.getText());
- oldExpr.append(chunk.getText());
- estimatedExpr.append(chunk.getText());
- break;
- case JRExpressionChunk.TYPE_PARAMETER:
- String paramName = getParameterVar(chunk.getText());
- defaultExpr.append(paramName);
- defaultExpr.append(".getValue()");
- oldExpr.append(paramName);
- oldExpr.append(".getValue()");
- estimatedExpr.append(paramName);
- estimatedExpr.append(".getValue()");
- break;
- case JRExpressionChunk.TYPE_VARIABLE:
- String varName = getVariableVar(chunk.getText());
- defaultExpr.append(varName);
- defaultExpr.append(".getValue()");
- oldExpr.append(varName);
- oldExpr.append(".getOldValue()");
- estimatedExpr.append(varName);
- estimatedExpr.append(".getEstimatedValue()");
- break;
- case JRExpressionChunk.TYPE_FIELD:
- String fieldName = getFieldVar(chunk.getText());
- defaultExpr.append(fieldName);
- defaultExpr.append(".getValue()");
- oldExpr.append(fieldName);
- oldExpr.append(".getOldValue()");
- estimatedExpr.append(fieldName);
- estimatedExpr.append(".getValue()");
- break;
- }
- }
- }
-
- return new JavaScriptCompileData.Expression(expression.getValueClassName(),
- defaultExpr.toString(), estimatedExpr.toString(), oldExpr.toString());
- }
- protected static String getParameterVar(String name)
- {
- return "param_" + JRStringUtil.getJavaIdentifier(name);
- }
- protected static String getVariableVar(String name)
- {
- return "var_" + JRStringUtil.getJavaIdentifier(name);
- }
- protected static String getFieldVar(String name)
- {
- return "field_" + JRStringUtil.getJavaIdentifier(name);
- }
-
- private final JavaScriptCompileData compileData;
- private Context context;
- private ScriptableObject scope;
- private Map loadedTypes = new HashMap();
- private Map compiledExpressions = new HashMap();
- /**
- * Create a JavaScript expression evaluator.
- *
- * @param compileData the report compile data
- */
- public JavaScriptEvaluator(JavaScriptCompileData compileData)
- {
- this.compileData = compileData;
- }
- protected void customizedInit(Map parametersMap, Map fieldsMap,
- Map variablesMap) throws JRException
- {
- context = ContextFactory.getGlobal().enterContext();//TODO exit context
- context.getWrapFactory().setJavaPrimitiveWrap(false);
- scope = context.initStandardObjects();
-
- for (Iterator it = parametersMap.entrySet().iterator(); it.hasNext();)
- {
- Map.Entry entry = (Map.Entry) it.next();
- String name = (String) entry.getKey();
- JRFillParameter param = (JRFillParameter) entry.getValue();
- JSParameter jsParam = new JSParameter(param, scope);
- scope.put(getParameterVar(name), scope, jsParam);
- }
- for (Iterator it = variablesMap.entrySet().iterator(); it.hasNext();)
- {
- Map.Entry entry = (Map.Entry) it.next();
- String name = (String) entry.getKey();
- JRFillVariable var = (JRFillVariable) entry.getValue();
- JSVariable jsVar = new JSVariable(var, scope);
- scope.put(getVariableVar(name), scope, jsVar);
- }
- if (fieldsMap != null)
- {
- for (Iterator it = fieldsMap.entrySet().iterator(); it.hasNext();)
- {
- Map.Entry entry = (Map.Entry) it.next();
- String name = (String) entry.getKey();
- JRFillField field = (JRFillField) entry.getValue();
- JSField jsField = new JSField(field, scope);
- scope.put(getFieldVar(name), scope, jsField);
- }
- }
- }
-
- protected Object evaluate(int id) throws Throwable //NOSONAR
- {
- JavaScriptCompileData.Expression expression = getExpression(id);
- return evaluateExpression(expression.getJavaType(),
- expression.getDefaultExpression());
- }
- protected Object evaluateEstimated(int id) throws Throwable //NOSONAR
- {
- JavaScriptCompileData.Expression expression = getExpression(id);
- return evaluateExpression(expression.getJavaType(),
- expression.getEstimatedExpression());
- }
- protected Object evaluateOld(int id) throws Throwable //NOSONAR
- {
- JavaScriptCompileData.Expression expression = getExpression(id);
- return evaluateExpression(expression.getJavaType(),
- expression.getOldExpression());
- }
- protected JavaScriptCompileData.Expression getExpression(int id)
- {
- return compileData.getExpression(id);
- }
-
- protected Object evaluateExpression(String type, String expression)
- {
- Script compiledExpression = getCompiledExpression(expression);
- Object value = compiledExpression.exec(context, scope);
-
- Class typeClass = getTypeClass(type);
- Object javaValue;
- try
- {
- javaValue = Context.jsToJava(value, typeClass);
- }
- catch (EvaluatorException e)
- {
- throw new JRRuntimeException(e);
- }
- return javaValue;
- }
-
- protected Script getCompiledExpression(String expression)
- {
- Script compiledExpression = (Script) compiledExpressions.get(expression);
- if (compiledExpression == null)
- {
- compiledExpression = context.compileString(expression, "expression", 0, null);
- compiledExpressions.put(expression, compiledExpression);
- }
- return compiledExpression;
- }
-
- protected Class getTypeClass(String type)
- {
- Class typeClass = (Class) loadedTypes.get(type);
- if (typeClass == null)
- {
- try
- {
- typeClass = JRClassLoader.loadClassForName(type);
- }
- catch (ClassNotFoundException e)
- {
- throw new JRRuntimeException("Unable to load class " + type, e);
- }
- loadedTypes.put(type, typeClass);
- }
- return typeClass;
- }
- }