View Javadoc

1   /*
2    * $Id: ExpressionTransformer.java 11834 2008-05-22 12:06:47Z rossmason $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.transformer.simple;
11  
12  import org.mule.api.MuleMessage;
13  import org.mule.api.lifecycle.InitialisationException;
14  import org.mule.api.transformer.TransformerException;
15  import org.mule.config.i18n.CoreMessages;
16  import org.mule.transformer.AbstractMessageAwareTransformer;
17  import org.mule.util.expression.ExpressionEvaluatorManager;
18  import org.mule.util.expression.ExpressionRuntimeException;
19  
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  /**
25   * This transformer will evaluate one or more expressions on the current message and return the
26   * results as an Array. If only one expression is defined it will return the object returned from
27   * the expression.
28   * <p/>
29   * You can use expressions to extract
30   * <ul>
31   * <li>headers (single, map or list)</li>
32   * <li>attachments (single, map or list)</li>
33   * <li>payload</li>
34   * <li>xpath</li>
35   * <li>groovy</li>
36   * <li>bean</li>
37   * </ul>
38   * and more.
39   * <p/>
40   * This transformer provides a very powerful way to pull different bits of information from the
41   * message and pass them to the service.
42   */
43  public class ExpressionTransformer extends AbstractMessageAwareTransformer
44  {
45      private List arguments;
46      private boolean returnSourceIfNull = false;
47  
48      public ExpressionTransformer()
49      {
50          //No type checking by default
51          registerSourceType(Object.class);
52          setReturnClass(Object.class);
53          arguments = new ArrayList(4);
54      }
55  
56      public void addArgument(Argument argument)
57      {
58          arguments.add(argument);
59      }
60  
61      public boolean removeArgument(Argument argument)
62      {
63          return arguments.remove(argument);
64      }
65  
66      /**
67       * Template method were deriving classes can do any initialisation after the
68       * properties have been set on this transformer
69       *
70       * @throws org.mule.api.lifecycle.InitialisationException
71       *
72       */
73      //@Override
74      public void initialise() throws InitialisationException
75      {
76          if (arguments == null || arguments.size() == 0)
77          {
78              throw new InitialisationException(CoreMessages.objectIsNull("arguments[]"), this);
79          }
80  
81          for (Iterator iterator = arguments.iterator(); iterator.hasNext();)
82          {
83              Argument argument = (Argument) iterator.next();
84              try
85              {
86                  argument.validate();
87              }
88              catch (Exception e)
89              {
90                  throw new InitialisationException(e, this);
91              }
92          }
93      }
94  
95      public Object transform(MuleMessage message, String outputEncoding) throws TransformerException
96      {
97          Object results[] = new Object[arguments.size()];
98          int i = 0;
99          for (Iterator iterator = arguments.iterator(); iterator.hasNext(); i++)
100         {
101             Argument argument = (Argument) iterator.next();
102             try
103             {
104                 results[i] = ExpressionEvaluatorManager.evaluate(argument.getFullExpression(), message);
105             }
106             catch (ExpressionRuntimeException e)
107             {
108                 throw new TransformerException(this, e);
109             }
110 
111             if (!argument.isOptional() && results[i] == null)
112             {
113                 throw new TransformerException(CoreMessages.expressionEvaluatorReturnedNull(
114                         argument.getEvaluator(), argument.getExpression()), this);
115 
116             }
117 
118         }
119         if (isReturnSourceIfNull() && checkIfAllAreNull(results))
120         {
121             return message;
122         }
123 
124         if (results.length == 1)
125         {
126             return results[0];
127         }
128         else
129         {
130             return results;
131         }
132     }
133 
134     private boolean checkIfAllAreNull(Object[] objects)
135     {
136         for (int i = 0; i < objects.length; i++)
137         {
138             if (objects[i] != null)
139             {
140                 return false;
141             }
142         }
143         return true;
144     }
145 
146     public List getArguments()
147     {
148         return arguments;
149     }
150 
151     public void setArguments(List arguments)
152     {
153         this.arguments = arguments;
154     }
155 
156     public boolean isReturnSourceIfNull()
157     {
158         return returnSourceIfNull;
159     }
160 
161     public void setReturnSourceIfNull(boolean returnSourceIfNull)
162     {
163         this.returnSourceIfNull = returnSourceIfNull;
164     }
165 
166     public static class Argument
167     {
168         public static final String EVAL_TOKEN = ":";
169         private String expression;
170         private String evaluator;
171         private String customEvaluator;
172         private boolean optional;
173 
174         public Argument()
175         {
176         }
177 
178         public String getCustomEvaluator()
179         {
180             return customEvaluator;
181         }
182 
183         public void setCustomEvaluator(String customEvaluator)
184         {
185             this.customEvaluator = customEvaluator;
186         }
187 
188         public String getEvaluator()
189         {
190             return evaluator;
191         }
192 
193         public void setEvaluator(String evaluator)
194         {
195             this.evaluator = evaluator;
196         }
197 
198         public String getExpression()
199         {
200             return expression;
201         }
202 
203         public void setExpression(String expression)
204         {
205             this.expression = expression;
206         }
207 
208         public boolean isOptional()
209         {
210             return optional;
211         }
212 
213         public void setOptional(boolean optional)
214         {
215             this.optional = optional;
216         }
217 
218         protected String getFullExpression()
219         {
220             //Sprecial handling of these evaluators since they don't retuen nul if some headers or attachments were found
221             if (!optional && (evaluator.equals("headers") || evaluator.equals("headers-list") ||
222                     (evaluator.equals("attachments") || evaluator.equals("attachments-list"))))
223             {
224                 return evaluator + EVAL_TOKEN + expression + "required";
225             }
226             return evaluator + EVAL_TOKEN + expression;
227         }
228 
229         protected void validate()
230         {
231             if (expression == null)
232             {
233                 throw new IllegalArgumentException(CoreMessages.objectIsNull("expression").getMessage());
234             }
235 
236             if (evaluator == null)
237             {
238                 throw new IllegalArgumentException(CoreMessages.objectIsNull("evaluator").getMessage());
239             }
240 
241             if (evaluator.equals("custom"))
242             {
243                 if (customEvaluator == null)
244                 {
245                     throw new IllegalArgumentException(CoreMessages.objectIsNull("customEvaluator").getMessage());
246                 }
247                 else
248                 {
249                     evaluator = customEvaluator;
250                 }
251             }
252 
253             if (!ExpressionEvaluatorManager.isEvaluatorRegistered(evaluator))
254             {
255                 throw new IllegalArgumentException(CoreMessages.expressionEvaluatorNotRegistered(evaluator).getMessage());
256             }
257         }
258     }
259 }