View Javadoc

1   /*
2    * $Id: AbstractScriptExpressionEvaluator.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  package org.mule.module.scripting.expression;
11  
12  import org.mule.api.MuleContext;
13  import org.mule.api.MuleMessage;
14  import org.mule.api.MuleRuntimeException;
15  import org.mule.api.context.MuleContextAware;
16  import org.mule.api.expression.ExpressionEvaluator;
17  import org.mule.api.lifecycle.Disposable;
18  import org.mule.api.lifecycle.InitialisationException;
19  import org.mule.config.i18n.CoreMessages;
20  import org.mule.module.scripting.component.Scriptable;
21  
22  import java.util.Map;
23  import java.util.WeakHashMap;
24  
25  import javax.script.Bindings;
26  import javax.script.ScriptException;
27  
28  /**
29   * An abstract {@link org.mule.api.expression.ExpressionEvaluator} that can be used for any JSR-233 script engine.
30   *
31   * If a POJO is passed in it is accessible from the 'payload' namespace.  If a {@link MuleMessage} instance is used then
32   * it is accessible from the message' namespace and the 'payload' namespace is also available.
33   */
34  public abstract class AbstractScriptExpressionEvaluator implements ExpressionEvaluator, Disposable, MuleContextAware
35  {
36      protected Map cache = new WeakHashMap(8);
37  
38      protected MuleContext muleContext;
39  
40      public void setMuleContext(MuleContext context)
41      {
42          this.muleContext = context;
43      }
44  
45      /**
46       * Extracts a single property from the message
47       *
48       * @param expression the property expression or expression
49       * @param message    the message to extract from
50       * @return the result of the extraction or null if the property was not found
51       */
52      public Object evaluate(String expression, MuleMessage message)
53      {
54          Scriptable script = getScript(expression);
55          script.setMuleContext(muleContext);
56          Bindings bindings = script.getScriptEngine().createBindings();
57          script.populateBindings(bindings, message);
58  
59          try
60          {
61              return script.runScript(bindings);
62          }
63          catch (ScriptException e)
64          {
65              return null;
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 }