View Javadoc

1   /*
2    * $Id: ExpressionArgument.java 20321 2010-11-24 15:21:24Z dfeist $
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.expression.transformers;
11  
12  import org.mule.api.MuleContext;
13  import org.mule.api.MuleMessage;
14  import org.mule.api.context.MuleContextAware;
15  import org.mule.api.expression.ExpressionRuntimeException;
16  import org.mule.api.transformer.Transformer;
17  import org.mule.api.transformer.TransformerException;
18  import org.mule.config.i18n.CoreMessages;
19  import org.mule.expression.ExpressionConfig;
20  import org.mule.transformer.types.DataTypeFactory;
21  
22  /**
23   * TODO
24   */
25  public class ExpressionArgument implements MuleContextAware
26  {
27      private ExpressionConfig expressionConfig = new ExpressionConfig();
28      private String name;
29      private boolean optional;
30      private Class<?> returnClass;
31      protected ClassLoader expressionEvaluationClassLoader = ExpressionArgument.class.getClassLoader();
32      private MuleContext muleContext;
33  
34      public ExpressionArgument()
35      {
36          super();
37      }
38  
39      public ExpressionArgument(String name, ExpressionConfig expressionConfig, boolean optional)
40      {
41          this(name, expressionConfig, optional, null);
42      }
43  
44      public ExpressionArgument(String name, ExpressionConfig expressionConfig, boolean optional, 
45          Class<?> returnClass)
46      {
47          this.expressionConfig = expressionConfig;
48          this.name = name;
49          this.optional = optional;
50          this.returnClass = returnClass;
51      }
52  
53      public void setMuleContext(MuleContext context)
54      {
55          this.muleContext = context;
56      }
57  
58      public String getName()
59      {
60          return name;
61      }
62  
63      public void setName(String name)
64      {
65          this.name = name;
66      }
67  
68      public ExpressionConfig getExpressionConfig()
69      {
70          return expressionConfig;
71      }
72  
73      public void setExpressionConfig(ExpressionConfig expressionConfig)
74      {
75          this.expressionConfig = expressionConfig;
76      }
77  
78      public boolean isOptional()
79      {
80          return optional;
81      }
82  
83      public void setOptional(boolean optional)
84      {
85          this.optional = optional;
86      }
87  
88      protected String getFullExpression()
89      {
90          return expressionConfig.getFullExpression(muleContext.getExpressionManager());
91      }
92  
93      protected void validate()
94      {
95          expressionConfig.validate(muleContext.getExpressionManager());
96      }
97  
98      /**
99       * Evaluates this Expression against the passed in Message.  If a returnClass is set on this Expression Argument it
100      * will be checked to ensure the Argument returns the correct class type.
101      * @param message the message to execute the expression on
102      * @return the result of the expression
103      * @throws ExpressionRuntimeException if the wrong return type is returned from the expression.
104      */
105     public Object evaluate(MuleMessage message) throws ExpressionRuntimeException
106     {
107         Object result = null;
108 
109         // MULE-4797 Because there is no way to specify the class-loader that script
110         // engines use and because scripts when used for expressions are compiled in
111         // runtime rather than at initialization the only way to ensure the correct
112         // class-loader to used is to switch it out here. We may want to consider
113         // passing the class-loader to the ExpressionManager and only doing this for
114         // certain ExpressionEvaluators further in.
115         ClassLoader originalContextClassLoader = Thread.currentThread().getContextClassLoader();
116         try
117         {
118             Thread.currentThread().setContextClassLoader(expressionEvaluationClassLoader);
119             result = muleContext.getExpressionManager().evaluate(getExpression(), getEvaluator(), message,
120                 !isOptional());
121         }
122         finally
123         {
124             // Restore original context class-loader
125             Thread.currentThread().setContextClassLoader(originalContextClassLoader);
126         }
127 
128         if (getReturnClass() != null && result != null)
129         {
130             if (!getReturnClass().isInstance(result))
131             {
132                 //If the return type does not match, lets attempt to transform it before throwing an error
133                 try
134                 {
135                     Transformer t = muleContext.getRegistry().lookupTransformer(
136                         DataTypeFactory.createFromObject(result), DataTypeFactory.create(getReturnClass()));
137                     result = t.transform(result);
138                 }
139                 catch (TransformerException e)
140                 {
141                     throw new ExpressionRuntimeException(CoreMessages.transformUnexpectedType(result.getClass(),
142                     getReturnClass()), e);
143                 }
144 
145             }
146 //            if(result instanceof Collection && ((Collection)result).size()==0 && !isOptional())
147 //            {
148 //                throw new ExpressionRuntimeException(CoreMessages.expressionEvaluatorReturnedNull(this.getEvaluator(), this.getExpression()));
149 //            }
150         }
151         return result;
152     }
153 
154     public String getExpression()
155     {
156         return expressionConfig.getExpression();
157     }
158 
159     public void setExpression(String expression)
160     {
161         expressionConfig.setExpression(expression);
162     }
163 
164     public String getEvaluator()
165     {
166         return expressionConfig.getEvaluator();
167     }
168     
169     public void setEvaluator(String evaluator)
170     {
171         expressionConfig.setEvaluator(evaluator);
172     }
173 
174     public void setCustomEvaluator(String evaluator)
175     {
176         expressionConfig.setCustomEvaluator(evaluator);
177     }
178 
179     public String getCustomEvaluator()
180     {
181         return expressionConfig.getCustomEvaluator();
182     }
183 
184     public Class<?> getReturnClass()
185     {
186         return returnClass;
187     }
188 
189     public void setReturnDataType(Class<?> returnClass)
190     {
191         this.returnClass = returnClass;
192     }
193     
194     public void setExpressionEvaluationClassLoader(ClassLoader expressionEvaluationClassLoader)
195     {
196         this.expressionEvaluationClassLoader = expressionEvaluationClassLoader;
197     }
198 
199 }