View Javadoc

1   /*
2    * $Id: JsonExpressionEvaluator.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.json;
11  
12  import org.mule.api.MuleMessage;
13  import org.mule.api.MuleRuntimeException;
14  import org.mule.api.expression.ExpressionEvaluator;
15  import org.mule.config.i18n.CoreMessages;
16  import org.mule.util.NumberUtils;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  
21  /**
22   * An expression evaluator to allow users to define json expressions in their mule configuration, i.e.
23   * <code>
24   * #[json:person/addresses[0]/postcode]
25   * </code>
26   * <p/>
27   * See the {@link org.mule.module.json.JsonData} object for mor information about the query syntax.
28   * <p/>
29   * It is also possible to use this evaluator in {@link org.mule.routing.filters.ExpressionFilter} objects. For example
30   * a filter could be defined as -
31   * <p/>
32   * <code>
33   * #[json:person/registered]
34   * </code>
35   * <p/>
36   * Where 'registered' is a boolean value.  It is also possible to filter on the existence of a value i.e.
37   * <p/>
38   * <code>
39   * #[json:person/favouriteColour]
40   * </code>
41   * <p/>
42   * Which would return true if 'favouriteColour' has been set. This evaluator also dds two logic operators you can use
43   * to create more sophisticated boolean expressions; equals and not equals -
44   * <p/>
45   * <code>
46   * #[json:person/favouriteColour = red]
47   * </code>
48   * <p/>
49   * or
50   * <p/>
51   * <code>
52   * #[json:person/favouriteColour != brown]
53   * </code>
54   *
55   * @see org.mule.module.json.JsonData
56   */
57  public class JsonExpressionEvaluator implements ExpressionEvaluator
58  {
59      /**
60       * logger used by this class
61       */
62      protected transient final Log logger = LogFactory.getLog(JsonExpressionEvaluator.class);
63  
64      public Object evaluate(String expression, MuleMessage message)
65      {
66          String compareTo = null;
67          boolean not = false;
68          int start = expression.lastIndexOf("/");
69          if (start == -1)
70          {
71              start = 0;
72          }
73          int i=0;
74          if ((i = expression.indexOf("!=", start)) > -1)
75          {
76              compareTo = expression.substring(i + 2, expression.length()).trim();
77              expression = expression.substring(0, i).trim();
78              not = true;
79          }
80          else if ((i = expression.indexOf("=", start)) > -1)
81          {
82              compareTo = expression.substring(i + 1, expression.length()).trim();
83              expression = expression.substring(0, i).trim();
84          }
85          
86          try
87          {
88              String json = message.getPayloadAsString();
89              JsonData data = new JsonData(json);
90              try
91              {
92                  Object result = data.get(expression);
93                  if (compareTo != null)
94                  {
95                      if (compareTo.equalsIgnoreCase("null"))
96                      {
97                          boolean answer = result == null;
98                          return (not ? !answer : answer);
99                      }
100                     else if (result instanceof Number && NumberUtils.isDigits(compareTo))
101                     {
102                         boolean answer = NumberUtils.createNumber(compareTo).equals(result);
103                         return (not ? !answer : answer);
104                     }
105                     else if (result instanceof Boolean && (compareTo.equalsIgnoreCase("true") || compareTo.equalsIgnoreCase("false")))
106                     {
107                         boolean answer = result.equals(Boolean.valueOf(compareTo));
108                         return (not ? !answer : answer);
109                     }
110                     else
111                     {
112                         boolean answer = compareTo.equals(result);
113                         return (not ? !answer : answer);
114                     }
115                 }
116                 else
117                 {
118                     return result;
119                 }
120             }
121             catch (IllegalArgumentException e)
122             {
123                 if (compareTo == null)
124                 {
125                     logger.debug("returning null for json expression: " + expression + ": " + e.getMessage());
126                     return null;
127                 }
128                 //If the element does not exist but is matching against 'null' return true, otherwise false
129                 return (compareTo.equalsIgnoreCase("null")) & !not;
130             }
131         }
132         catch (Exception e)
133         {
134             throw new MuleRuntimeException(CoreMessages.failedToProcessExtractorFunction(getName() + ":" + expression), e);
135         }
136     }
137 
138     public void setName(String name)
139     {
140         throw new UnsupportedOperationException("setName");
141     }
142 
143     public String getName()
144     {
145         return "json";
146     }
147 }