001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.model.language;
018
019 import java.util.List;
020
021 import javax.xml.bind.annotation.XmlAccessType;
022 import javax.xml.bind.annotation.XmlAccessorType;
023 import javax.xml.bind.annotation.XmlAttribute;
024 import javax.xml.bind.annotation.XmlID;
025 import javax.xml.bind.annotation.XmlRootElement;
026 import javax.xml.bind.annotation.XmlTransient;
027 import javax.xml.bind.annotation.XmlType;
028 import javax.xml.bind.annotation.XmlValue;
029 import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
030 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
031
032 import org.apache.camel.CamelContext;
033 import org.apache.camel.Exchange;
034 import org.apache.camel.Expression;
035 import org.apache.camel.Predicate;
036 import org.apache.camel.spi.Language;
037 import org.apache.camel.spi.Required;
038 import org.apache.camel.spi.RouteContext;
039 import org.apache.camel.util.CollectionStringBuffer;
040 import org.apache.camel.util.ExpressionToPredicateAdapter;
041 import org.apache.camel.util.IntrospectionSupport;
042 import org.apache.camel.util.ObjectHelper;
043
044 /**
045 * A useful base class for an expression
046 *
047 * @version
048 */
049 @XmlRootElement
050 @XmlType(name = "expression")
051 @XmlAccessorType(XmlAccessType.FIELD)
052 public class ExpressionDefinition implements Expression, Predicate {
053 @XmlAttribute
054 @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
055 @XmlID
056 private String id;
057 @XmlValue
058 private String expression;
059 @XmlAttribute
060 private Boolean trim;
061 @XmlTransient
062 private Predicate predicate;
063 @XmlTransient
064 private Expression expressionValue;
065 @XmlTransient
066 private ExpressionDefinition expressionType;
067
068 public ExpressionDefinition() {
069 }
070
071 public ExpressionDefinition(String expression) {
072 this.expression = expression;
073 }
074
075 public ExpressionDefinition(Predicate predicate) {
076 this.predicate = predicate;
077 }
078
079 public ExpressionDefinition(Expression expression) {
080 this.expressionValue = expression;
081 }
082
083 public static String getLabel(List<ExpressionDefinition> expressions) {
084 CollectionStringBuffer buffer = new CollectionStringBuffer();
085 for (ExpressionDefinition expression : expressions) {
086 buffer.append(expression.getLabel());
087 }
088 return buffer.toString();
089 }
090
091 @Override
092 public String toString() {
093 StringBuilder sb = new StringBuilder();
094 if (getLanguage() != null) {
095 sb.append(getLanguage()).append("{");
096 }
097 if (getPredicate() != null) {
098 sb.append(getPredicate().toString());
099 }
100 if (getExpressionValue() != null) {
101 sb.append(getExpressionValue().toString());
102 }
103 if (getPredicate() == null && getExpressionValue() == null && getExpression() != null) {
104 sb.append(getExpression());
105 }
106 if (getLanguage() != null) {
107 sb.append("}");
108 }
109 return sb.toString();
110 }
111
112 public Object evaluate(Exchange exchange) {
113 return evaluate(exchange, Object.class);
114 }
115
116 public <T> T evaluate(Exchange exchange, Class<T> type) {
117 if (expressionValue == null) {
118 expressionValue = createExpression(exchange.getContext());
119 }
120 ObjectHelper.notNull(expressionValue, "expressionValue");
121 return expressionValue.evaluate(exchange, type);
122 }
123
124 public void assertMatches(String text, Exchange exchange) throws AssertionError {
125 if (!matches(exchange)) {
126 throw new AssertionError(text + getExpression() + " for exchange: " + exchange);
127 }
128 }
129
130 public boolean matches(Exchange exchange) {
131 if (predicate == null) {
132 predicate = createPredicate(exchange.getContext());
133 }
134 ObjectHelper.notNull(predicate, "predicate");
135 return predicate.matches(exchange);
136 }
137
138 public String getLanguage() {
139 return "";
140 }
141
142 public final Predicate createPredicate(RouteContext routeContext) {
143 return createPredicate(routeContext.getCamelContext());
144 }
145
146 public Predicate createPredicate(CamelContext camelContext) {
147 if (predicate == null) {
148 if (getExpressionType() != null) {
149 predicate = getExpressionType().createPredicate(camelContext);
150 } else if (getExpressionValue() != null) {
151 predicate = new ExpressionToPredicateAdapter(getExpressionValue());
152 } else if (getExpression() != null) {
153 ObjectHelper.notNull("language", getLanguage());
154 Language language = camelContext.resolveLanguage(getLanguage());
155 String exp = getExpression();
156 // trim if configured to trim
157 if (exp != null && isTrim()) {
158 exp = exp.trim();
159 }
160 predicate = language.createPredicate(exp);
161 configurePredicate(camelContext, predicate);
162 }
163 }
164 return predicate;
165 }
166
167 public final Expression createExpression(RouteContext routeContext) {
168 return createExpression(routeContext.getCamelContext());
169 }
170
171 public Expression createExpression(CamelContext camelContext) {
172 if (getExpressionValue() == null) {
173 if (getExpressionType() != null) {
174 setExpressionValue(getExpressionType().createExpression(camelContext));
175 } else if (getExpression() != null) {
176 ObjectHelper.notNull("language", getLanguage());
177 Language language = camelContext.resolveLanguage(getLanguage());
178 String exp = getExpression();
179 // trim if configured to trim
180 if (exp != null && isTrim()) {
181 exp = exp.trim();
182 }
183 setExpressionValue(language.createExpression(exp));
184 configureExpression(camelContext, getExpressionValue());
185 }
186 }
187 return getExpressionValue();
188 }
189
190 public String getExpression() {
191 return expression;
192 }
193
194 @Required
195 public void setExpression(String expression) {
196 this.expression = expression;
197 }
198
199 /**
200 * Gets the value of the id property.
201 */
202 public String getId() {
203 return id;
204 }
205
206 /**
207 * Sets the value of the id property.
208 */
209 public void setId(String value) {
210 this.id = value;
211 }
212
213 public Predicate getPredicate() {
214 return predicate;
215 }
216
217 public Expression getExpressionValue() {
218 return expressionValue;
219 }
220
221 protected void setExpressionValue(Expression expressionValue) {
222 this.expressionValue = expressionValue;
223 }
224
225 public ExpressionDefinition getExpressionType() {
226 return expressionType;
227 }
228
229 public Boolean getTrim() {
230 return trim;
231 }
232
233 public void setTrim(Boolean trim) {
234 this.trim = trim;
235 }
236
237 public boolean isTrim() {
238 // trim by default
239 return trim == null || trim;
240 }
241
242 /**
243 * Returns some descriptive text to describe this node
244 */
245 public String getLabel() {
246 String language = getExpression();
247 if (ObjectHelper.isEmpty(language)) {
248 Predicate predicate = getPredicate();
249 if (predicate != null) {
250 return predicate.toString();
251 }
252 Expression expressionValue = getExpressionValue();
253 if (expressionValue != null) {
254 return expressionValue.toString();
255 }
256 } else {
257 return language;
258 }
259 return "";
260 }
261
262 /**
263 * Allows derived classes to set a lazily created expressionType instance
264 * such as if using the {@link org.apache.camel.builder.ExpressionClause}
265 */
266 protected void setExpressionType(ExpressionDefinition expressionType) {
267 this.expressionType = expressionType;
268 }
269
270 protected void configurePredicate(CamelContext camelContext, Predicate predicate) {
271 }
272
273 protected void configureExpression(CamelContext camelContext, Expression expression) {
274 }
275
276 /**
277 * Sets a named property on the object instance using introspection
278 */
279 protected void setProperty(Object bean, String name, Object value) {
280 try {
281 IntrospectionSupport.setProperty(bean, name, value);
282 } catch (Exception e) {
283 throw new IllegalArgumentException("Failed to set property " + name + " on " + bean
284 + ". Reason: " + e, e);
285 }
286 }
287 }