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