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: 751655 $
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 if (expressionValue == null) {
112 RouteContext routeContext = new DefaultRouteContext(exchange.getContext());
113 expressionValue = createExpression(routeContext);
114 }
115 ObjectHelper.notNull(expressionValue, "expressionValue");
116 return expressionValue.evaluate(exchange);
117 }
118
119 public <T> T evaluate(Exchange exchange, Class<T> type) {
120 if (expressionValue == null) {
121 RouteContext routeContext = new DefaultRouteContext(exchange.getContext());
122 expressionValue = createExpression(routeContext);
123 }
124 ObjectHelper.notNull(expressionValue, "expressionValue");
125 return expressionValue.evaluate(exchange, type);
126 }
127
128 public void assertMatches(String text, Exchange exchange) throws AssertionError {
129 if (!matches(exchange)) {
130 throw new AssertionError(text + getExpression() + " for exchange: " + exchange);
131 }
132 }
133
134 public boolean matches(Exchange exchange) {
135 if (predicate == null) {
136 RouteContext routeContext = new DefaultRouteContext(exchange.getContext());
137 predicate = createPredicate(routeContext);
138 }
139 ObjectHelper.notNull(predicate, "predicate");
140 return predicate.matches(exchange);
141 }
142
143 public String getLanguage() {
144 return "";
145 }
146
147 public Predicate createPredicate(RouteContext routeContext) {
148 if (predicate == null) {
149 if (expressionType != null) {
150 predicate = expressionType.createPredicate(routeContext);
151 } else if (expressionValue != null) {
152 predicate = PredicateBuilder.toPredicate(expressionValue);
153 } else if (getExpression() != null) {
154 ObjectHelper.notNull("language", getLanguage());
155 CamelContext camelContext = routeContext.getCamelContext();
156 Language language = camelContext.resolveLanguage(getLanguage());
157 predicate = language.createPredicate(getExpression());
158 configurePredicate(routeContext, predicate);
159 }
160 }
161 return predicate;
162 }
163
164 public Expression createExpression(RouteContext routeContext) {
165 if (expressionValue == null) {
166 if (expressionType != null) {
167 expressionValue = expressionType.createExpression(routeContext);
168 } else if (getExpression() != null) {
169 ObjectHelper.notNull("language", getLanguage());
170 CamelContext camelContext = routeContext.getCamelContext();
171 Language language = camelContext.resolveLanguage(getLanguage());
172 expressionValue = language.createExpression(getExpression());
173 configureExpression(routeContext, expressionValue);
174 }
175 }
176 return expressionValue;
177 }
178
179 public String getExpression() {
180 return expression;
181 }
182
183 public void setExpression(String expression) {
184 this.expression = expression;
185 }
186
187 /**
188 * Gets the value of the id property.
189 */
190 public String getId() {
191 return id;
192 }
193
194 /**
195 * Sets the value of the id property.
196 */
197 public void setId(String value) {
198 this.id = value;
199 }
200
201 public Predicate getPredicate() {
202 return predicate;
203 }
204
205 public Expression getExpressionValue() {
206 return expressionValue;
207 }
208
209 protected void setExpressionValue(Expression expressionValue) {
210 this.expressionValue = expressionValue;
211 }
212
213 /**
214 * Returns some descriptive text to describe this node
215 */
216 public String getLabel() {
217 String language = getExpression();
218 if (ObjectHelper.isEmpty(language)) {
219 Predicate predicate = getPredicate();
220 if (predicate != null) {
221 return predicate.toString();
222 }
223 Expression expressionValue = getExpressionValue();
224 if (expressionValue != null) {
225 return expressionValue.toString();
226 }
227 } else {
228 return language;
229 }
230 return "";
231 }
232
233 /**
234 * Allows derived classes to set a lazily created expressionType instance
235 * such as if using the {@link org.apache.camel.builder.ExpressionClause}
236 */
237 protected void setExpressionType(ExpressionDefinition expressionType) {
238 this.expressionType = expressionType;
239 }
240
241 protected void configurePredicate(RouteContext routeContext, Predicate predicate) {
242 }
243
244 protected void configureExpression(RouteContext routeContext, Expression expression) {
245 }
246
247 /**
248 * Sets a named property on the object instance using introspection
249 */
250 protected void setProperty(Object bean, String name, Object value) {
251 try {
252 IntrospectionSupport.setProperty(bean, name, value);
253 } catch (Exception e) {
254 throw new IllegalArgumentException("Failed to set property " + name + " on " + bean
255 + ". Reason: " + e, e);
256 }
257 }
258 }