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