View Javadoc

1   /*
2    * $Id: ValueExtractorTransformer.java 23202 2011-10-17 21:16:01Z pablo.kraan $
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  
11  package org.mule.transformer.simple;
12  
13  import org.mule.api.MuleMessage;
14  import org.mule.api.transformer.TransformerException;
15  import org.mule.transformer.AbstractMessageTransformer;
16  
17  import java.util.Collections;
18  import java.util.List;
19  import java.util.regex.Matcher;
20  import java.util.regex.Pattern;
21  
22  /**
23   * Extracts values from a given source using regular expressions and uses
24   * that values to enrich the mule message.
25   */
26  public class ValueExtractorTransformer extends AbstractMessageTransformer
27  {
28  
29      // MULE-5815: default should be #[payload] but that value is not a valid expression
30      public static final String DEFAULT_SOURCE_EXPRESSION = "#[payload:]";
31  
32      private String source = DEFAULT_SOURCE_EXPRESSION;
33      private List<ValueExtractorTemplate> valueExtractorTemplates;
34  
35      public ValueExtractorTransformer()
36      {
37          // Default constructor required by spring
38      }
39  
40      @Override
41      public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException
42      {
43          String valueToMatch = getValueToMatch(message);
44  
45          for (ValueExtractorTemplate valueExtractorTemplate : valueExtractorTemplates)
46          {
47              Matcher matcher = valueExtractorTemplate.compiledPattern.matcher(valueToMatch);
48  
49              if (matcher.matches())
50              {
51                  if (matcher.groupCount() != 1)
52                  {
53                      throw new IllegalStateException("Matched regular expression must contain one capture group but contains " + matcher.groupCount());
54                  }
55  
56                  //TODO: there should be a way to decide which group/groups values should be used to enrich the message
57                  muleContext.getExpressionManager().enrich(valueExtractorTemplate.getTarget(), message, matcher.group(1));
58              }
59              else
60              {
61                  if (valueExtractorTemplate.failIfNoMatch)
62                  {
63                      throw new IllegalStateException(String.format("Source value '%s' does not math pattern '%s'", valueToMatch, valueExtractorTemplate.getPattern()));
64                  }
65                  else
66                  {
67                      if (valueExtractorTemplate.defaultValue != null)
68                      {
69                          muleContext.getExpressionManager().enrich(valueExtractorTemplate.getTarget(), message, valueExtractorTemplate.defaultValue);
70                      }
71                  }
72              }
73          }
74  
75          return message;
76      }
77  
78      private String getValueToMatch(MuleMessage message)
79      {
80          if (muleContext.getExpressionManager().isValidExpression(source))
81          {
82              Object result = muleContext.getExpressionManager().evaluate(source, message, true);
83  
84              if (result instanceof String)
85              {
86                  return (String) result;
87              }
88              else
89              {
90                  throw new IllegalArgumentException("String value expected but received value is " + result.getClass().getName());
91              }
92          }
93          else
94          {
95              return source;
96          }
97      }
98  
99      public String getSource()
100     {
101         return source;
102     }
103 
104     public void setSource(String source)
105     {
106         this.source = source;
107     }
108 
109     public List<ValueExtractorTemplate> getValueExtractorTemplates()
110     {
111         return Collections.unmodifiableList(valueExtractorTemplates);
112     }
113 
114     public void setValueExtractorTemplates(List<ValueExtractorTemplate> ValueExtractorTemplates)
115     {
116         this.valueExtractorTemplates = ValueExtractorTemplates;
117     }
118 
119     public static class ValueExtractorTemplate
120     {
121 
122         private String pattern;
123         private String target;
124         private boolean failIfNoMatch;
125         private Pattern compiledPattern;
126         private String defaultValue;
127 
128         @SuppressWarnings({"UnusedDeclaration"})
129         public ValueExtractorTemplate()
130         {
131             // Default constructor required by Spring
132         }
133 
134         public ValueExtractorTemplate(String pattern, String target, boolean failIfNoMatch, String defaultValue)
135         {
136             this.defaultValue = defaultValue;
137             setPattern(pattern);
138             this.target = target;
139             this.failIfNoMatch = failIfNoMatch;
140         }
141 
142         public String getPattern()
143         {
144             return pattern;
145         }
146 
147         public void setPattern(String pattern)
148         {
149             this.pattern = pattern;
150             compiledPattern = Pattern.compile(pattern);
151         }
152 
153         public String getTarget()
154         {
155             return target;
156         }
157 
158         public void setTarget(String target)
159         {
160             this.target = target;
161         }
162 
163         public boolean isFailIfNoMatch()
164         {
165             return failIfNoMatch;
166         }
167 
168         public void setFailIfNoMatch(boolean failIfNoMatch)
169         {
170             this.failIfNoMatch = failIfNoMatch;
171         }
172 
173         public String getDefaultValue()
174         {
175             return defaultValue;
176         }
177 
178         public void setDefaultValue(String defaultValue)
179         {
180             this.defaultValue = defaultValue;
181         }
182     }
183 }