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.builder.PredicateBuilder;
037 import org.apache.camel.impl.DefaultRouteContext;
038 import org.apache.camel.spi.Language;
039 import org.apache.camel.spi.RouteContext;
040 import org.apache.camel.util.CollectionStringBuffer;
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 $Revision: 900466 $
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 @XmlTransient
060 private Predicate predicate;
061 @XmlTransient
062 private Expression expressionValue;
063 @XmlTransient
064 private ExpressionDefinition expressionType;
065
066 public ExpressionDefinition() {
067 }
068
069 public ExpressionDefinition(String expression) {
070 this.expression = expression;
071 }
072
073 public ExpressionDefinition(Predicate predicate) {
074 this.predicate = predicate;
075 }
076
077 public ExpressionDefinition(Expression expression) {
078 this.expressionValue = expression;
079 }
080
081 public static String getLabel(List<ExpressionDefinition> expressions) {
082 CollectionStringBuffer buffer = new CollectionStringBuffer();
083 for (ExpressionDefinition expression : expressions) {
084 buffer.append(expression.getLabel());
085 }
086 return buffer.toString();
087 }
088
089 @Override
090 public String toString() {
091 StringBuilder sb = new StringBuilder();
092 if (getLanguage() != null) {
093 sb.append(getLanguage()).append("{");
094 }
095 if (getExpression() != null) {
096 sb.append(getExpression());
097 }
098 if (getPredicate() != null) {
099 sb.append(getPredicate().toString());
100 }
101 if (getExpressionValue() != null) {
102 sb.append(getExpressionValue().toString());
103 }
104 if (getLanguage() != null) {
105 sb.append("}");
106 }
107 return sb.toString();
108 }
109
110 public Object evaluate(Exchange exchange) {
111 return evaluate(exchange, Object.class);
112 }
113
114 public <T> T evaluate(Exchange exchange, Class<T> type) {
115 if (expressionValue == null) {
116 expressionValue = createExpression(exchange.getContext());
117 }
118 ObjectHelper.notNull(expressionValue, "expressionValue");
119 return expressionValue.evaluate(exchange, type);
120 }
121
122 public void assertMatches(String text, Exchange exchange) throws AssertionError {
123 if (!matches(exchange)) {
124 throw new AssertionError(text + getExpression() + " for exchange: " + exchange);
125 }
126 }
127
128 public boolean matches(Exchange exchange) {
129 if (predicate == null) {
130 predicate = createPredicate(exchange.getContext());
131 }
132 ObjectHelper.notNull(predicate, "predicate");
133 return predicate.matches(exchange);
134 }
135
136 public String getLanguage() {
137 return "";
138 }
139
140 public final Predicate createPredicate(RouteContext routeContext) {
141 return createPredicate(routeContext.getCamelContext());
142 }
143
144 public Predicate createPredicate(CamelContext camelContext) {
145 if (predicate == null) {
146 if (getExpressionType() != null) {
147 predicate = getExpressionType().createPredicate(camelContext);
148 } else if (getExpressionValue() != null) {
149 predicate = PredicateBuilder.toPredicate(getExpressionValue());
150 } else if (getExpression() != null) {
151 ObjectHelper.notNull("language", getLanguage());
152 Language language = camelContext.resolveLanguage(getLanguage());
153 predicate = language.createPredicate(getExpression());
154 configurePredicate(camelContext, predicate);
155 }
156 }
157 return predicate;
158 }
159
160 public final Expression createExpression(RouteContext routeContext) {
161 return createExpression(routeContext.getCamelContext());
162 }
163
164 public Expression createExpression(CamelContext camelContext) {
165 if (getExpressionValue() == null) {
166 if (getExpressionType() != null) {
167 setExpressionValue(getExpressionType().createExpression(camelContext));
168 } else if (getExpression() != null) {
169 ObjectHelper.notNull("language", getLanguage());
170 Language language = camelContext.resolveLanguage(getLanguage());
171 setExpressionValue(language.createExpression(getExpression()));
172 configureExpression(camelContext, getExpressionValue());
173 }
174 }
175 return getExpressionValue();
176 }
177
178 public String getExpression() {
179 return expression;
180 }
181
182 public void setExpression(String expression) {
183 this.expression = expression;
184 }
185
186 /**
187 * Gets the value of the id property.
188 */
189 public String getId() {
190 return id;
191 }
192
193 /**
194 * Sets the value of the id property.
195 */
196 public void setId(String value) {
197 this.id = value;
198 }
199
200 public Predicate getPredicate() {
201 return predicate;
202 }
203
204 public Expression getExpressionValue() {
205 return expressionValue;
206 }
207
208 protected void setExpressionValue(Expression expressionValue) {
209 this.expressionValue = expressionValue;
210 }
211
212 public ExpressionDefinition getExpressionType() {
213 return expressionType;
214 }
215
216 /**
217 * Returns some descriptive text to describe this node
218 */
219 public String getLabel() {
220 String language = getExpression();
221 if (ObjectHelper.isEmpty(language)) {
222 Predicate predicate = getPredicate();
223 if (predicate != null) {
224 return predicate.toString();
225 }
226 Expression expressionValue = getExpressionValue();
227 if (expressionValue != null) {
228 return expressionValue.toString();
229 }
230 } else {
231 return language;
232 }
233 return "";
234 }
235
236 /**
237 * Allows derived classes to set a lazily created expressionType instance
238 * such as if using the {@link org.apache.camel.builder.ExpressionClause}
239 */
240 protected void setExpressionType(ExpressionDefinition expressionType) {
241 this.expressionType = expressionType;
242 }
243
244 protected void configurePredicate(CamelContext camelContext, Predicate predicate) {
245 }
246
247 protected void configureExpression(CamelContext camelContext, Expression expression) {
248 }
249
250 /**
251 * Sets a named property on the object instance using introspection
252 */
253 protected void setProperty(Object bean, String name, Object value) {
254 try {
255 IntrospectionSupport.setProperty(bean, name, value);
256 } catch (Exception e) {
257 throw new IllegalArgumentException("Failed to set property " + name + " on " + bean
258 + ". Reason: " + e, e);
259 }
260 }
261 }