View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.scripting.expression;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.MuleRuntimeException;
12  import org.mule.api.context.MuleContextAware;
13  import org.mule.api.expression.ExpressionEvaluator;
14  import org.mule.api.lifecycle.Disposable;
15  import org.mule.api.lifecycle.InitialisationException;
16  import org.mule.config.i18n.CoreMessages;
17  import org.mule.module.scripting.component.Scriptable;
18  
19  import java.util.Map;
20  import java.util.WeakHashMap;
21  
22  import javax.script.Bindings;
23  import javax.script.ScriptException;
24  
25  /**
26   * An abstract {@link org.mule.api.expression.ExpressionEvaluator} that can be used for any JSR-233 script engine.
27   *
28   * If a POJO is passed in it is accessible from the 'payload' namespace.  If a {@link MuleMessage} instance is used then
29   * it is accessible from the message' namespace and the 'payload' namespace is also available.
30   */
31  public abstract class AbstractScriptExpressionEvaluator implements ExpressionEvaluator, Disposable, MuleContextAware
32  {
33      protected Map cache = new WeakHashMap(8);
34  
35      protected MuleContext muleContext;
36  
37      public void setMuleContext(MuleContext context)
38      {
39          this.muleContext = context;
40      }
41  
42      /**
43       * Extracts a single property from the message
44       *
45       * @param expression the property expression or expression
46       * @param message    the message to extract from
47       * @return the result of the extraction or null if the property was not found
48       */
49      public Object evaluate(String expression, MuleMessage message)
50      {
51          Scriptable script = getScript(expression);
52          script.setMuleContext(muleContext);
53          Bindings bindings = script.getScriptEngine().createBindings();
54          script.populateBindings(bindings, message);
55  
56          try
57          {
58              return script.runScript(bindings);
59          }
60          catch (ScriptException e)
61          {
62              throw new MuleRuntimeException(e);
63          }
64          finally {
65              bindings.clear();
66          }
67      }
68  
69      /**
70       * Sets the name of the object
71       *
72       * @param name the name of the object
73       */
74      public void setName(String name)
75      {
76          throw new UnsupportedOperationException("setName");
77      }
78  
79      protected Scriptable getScript(String expression)
80      {
81          Scriptable script = (Scriptable)cache.get(expression);
82          if (script==null)
83          {
84              script = new Scriptable(muleContext);
85              script.setScriptEngineName(getName());
86              script.setScriptText(expression);
87              try
88              {
89                  script.initialise();
90              }
91              catch (InitialisationException e)
92              {
93                  throw new MuleRuntimeException(
94                      CoreMessages.initialisationFailure("An error occurred initialising script."), e);
95              }
96              cache.put(expression, script);
97          }
98          return script;
99      }
100 
101     /**
102      * A lifecycle method where implementor should free up any resources. If an
103      * exception is thrown it should just be logged and processing should continue.
104      * This method should not throw Runtime exceptions.
105      */
106     public void dispose()
107     {
108         cache.clear();
109     }
110 }