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