001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.automation.core.scripting; 013 014import java.io.Serializable; 015import java.util.HashMap; 016import java.util.Map; 017 018import org.mvel2.MVEL; 019import org.mvel2.compiler.BlankLiteral; 020import org.nuxeo.ecm.automation.OperationContext; 021import org.nuxeo.ecm.automation.core.Constants; 022import org.nuxeo.ecm.automation.core.trace.TracerFactory; 023import org.nuxeo.runtime.api.Framework; 024 025/** 026 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 027 */ 028public class MvelExpression implements Expression { 029 030 private static final long serialVersionUID = 1L; 031 032 protected transient volatile Serializable compiled; 033 034 protected final String expr; 035 036 public MvelExpression(String expr) { 037 this.expr = expr; 038 } 039 040 @Override 041 public Object eval(OperationContext ctx) { 042 if (compiled == null) { 043 compiled = MVEL.compileExpression(expr); 044 } 045 Object result; 046 047 // Get and/or Store mvel results in operation context in case when trace mode enabled 048 TracerFactory factory = Framework.getService(TracerFactory.class); 049 if (factory.getRecordingState()) { 050 HashMap<String, Object> mvelResults = (HashMap<String, Object>) ctx.get(Constants.MVEL_RESULTS); 051 if (mvelResults == null) { 052 mvelResults = new HashMap<>(); 053 } 054 if (mvelResults.get(expr) != null) { 055 result = mvelResults.get(expr); 056 } else { 057 result = MVEL.executeExpression(compiled, getBindings(ctx)); 058 mvelResults.put(expr, result); 059 ctx.put(Constants.MVEL_RESULTS, mvelResults); 060 } 061 } else { 062 result = MVEL.executeExpression(compiled, getBindings(ctx)); 063 } 064 065 return result != null && result.getClass().isAssignableFrom(BlankLiteral.class) ? "" : result; 066 } 067 068 /** 069 * @since 5.9.3 070 */ 071 protected Map<String, Object> getBindings(OperationContext ctx) { 072 return Scripting.initBindings(ctx); 073 } 074}