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