/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.el.mvel; import org.mule.runtime.core.api.MuleContext; import org.mule.runtime.core.api.el.ExpressionLanguageContext; import org.mule.runtime.core.api.el.ExpressionLanguageFunction; import org.mule.runtime.core.api.el.VariableAssignmentCallback; import org.mule.runtime.core.config.i18n.CoreMessages; import org.mule.mvel2.ImmutableElementException; import org.mule.mvel2.ParserConfiguration; import org.mule.mvel2.ParserContext; import org.mule.mvel2.ast.FunctionInstance; import org.mule.mvel2.compiler.AbstractParser; import org.mule.mvel2.integration.VariableResolver; import java.lang.reflect.Method; public class MVELExpressionLanguageContext extends MuleBaseVariableResolverFactory implements ExpressionLanguageContext { private static final long serialVersionUID = 909413730991198290L; public static final String MULE_MESSAGE_INTERNAL_VARIABLE = "_muleMessage"; public static final String MULE_EVENT_INTERNAL_VARIABLE = "_muleEvent"; public static final String MULE_CONTEXT_INTERNAL_VARIABLE = "_muleContext"; protected ParserConfiguration parserConfiguration; protected MuleContext muleContext; public MVELExpressionLanguageContext(ParserConfiguration parserConfiguration, MuleContext muleContext) { this.parserConfiguration = parserConfiguration; this.muleContext = muleContext; } public MVELExpressionLanguageContext(MVELExpressionLanguageContext context) { this.parserConfiguration = context.parserConfiguration; this.muleContext = context.muleContext; this.nextFactory = context.nextFactory; this.variableResolvers = context.variableResolvers; } @Override public VariableResolver getVariableResolver(String name) { VariableResolver variableResolver = super.getVariableResolver(name); // In order to allow aliases to use message context without requiring the creating of a // GlobalVariableResolver for each expression evaluation, we create a new resolver on the fly with // current context instead. if (variableResolver instanceof MuleAliasVariableResolver) { variableResolver = new MuleAliasVariableResolver((MuleAliasVariableResolver) variableResolver, this); } return variableResolver; } /* * (non-Javadoc) * * @see org.mule.runtime.core.el.mvel.MuleVariableResolverFactory#addVariable(java.lang.String, java.lang.Object) */ @Override public <T> void addVariable(String name, T value) { addResolver(name, new MuleVariableResolver<T>(name, value, value != null ? value.getClass() : null, null)); } @Override public <T> void addVariable(String name, T value, VariableAssignmentCallback<T> assignmentCallback) { addResolver(name, new MuleVariableResolver<T>(name, value, value != null ? value.getClass() : null, assignmentCallback)); } @Override public <T> void addFinalVariable(String name, T value) { addVariable(name, value, new VariableAssignmentCallback<T>() { @Override public void assignValue(String name, T value, T newValue) { throw new ImmutableElementException(CoreMessages.expressionFinalVariableCannotBeAssignedValue(name).getMessage()); } }); } @SuppressWarnings("unchecked") @Override public <T> T getVariable(String name) { VariableResolver resolver = getVariableResolver(name); if (resolver != null) { return (T) resolver.getValue(); } else { return null; } } @SuppressWarnings("unchecked") @Override public <T> T getVariable(String name, Class<T> type) { return (T) getVariable(name); } @Override public void addAlias(String alias, String expression) { addResolver(alias, new MuleAliasVariableResolver(alias, expression, this, parserConfiguration)); } @Override public void importClass(Class<?> clazz) { if (parserConfiguration.hasImport(clazz.getSimpleName())) { parserConfiguration.addImport(clazz); } } @Override public void importClass(String name, Class<?> clazz) { if (!parserConfiguration.hasImport(name)) { parserConfiguration.addImport(name, clazz); } } @Override public void importStaticMethod(String name, Method method) { if (!parserConfiguration.hasImport(name)) { parserConfiguration.addImport(name, method); } } @Override public boolean contains(String name) { return isResolveable(name); } @Override public void declareFunction(String name, ExpressionLanguageFunction function) { try { addFinalVariable(name, new FunctionInstance(new MVELFunctionAdaptor(name, function, new ParserContext(parserConfiguration)))); } finally { // Clear AbstractParser.parserContext ThreadLocal once Function has been created. AbstractParser.resetParserContext(); } } }