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.spi.Language; 037 import org.apache.camel.spi.Required; 038 import org.apache.camel.spi.RouteContext; 039 import org.apache.camel.util.CollectionStringBuffer; 040 import org.apache.camel.util.ExpressionToPredicateAdapter; 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 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 @XmlAttribute 060 private Boolean trim; 061 @XmlTransient 062 private Predicate predicate; 063 @XmlTransient 064 private Expression expressionValue; 065 @XmlTransient 066 private ExpressionDefinition expressionType; 067 068 public ExpressionDefinition() { 069 } 070 071 public ExpressionDefinition(String expression) { 072 this.expression = expression; 073 } 074 075 public ExpressionDefinition(Predicate predicate) { 076 this.predicate = predicate; 077 } 078 079 public ExpressionDefinition(Expression expression) { 080 this.expressionValue = expression; 081 } 082 083 public static String getLabel(List<ExpressionDefinition> expressions) { 084 CollectionStringBuffer buffer = new CollectionStringBuffer(); 085 for (ExpressionDefinition expression : expressions) { 086 buffer.append(expression.getLabel()); 087 } 088 return buffer.toString(); 089 } 090 091 @Override 092 public String toString() { 093 StringBuilder sb = new StringBuilder(); 094 if (getLanguage() != null) { 095 sb.append(getLanguage()).append("{"); 096 } 097 if (getPredicate() != null) { 098 sb.append(getPredicate().toString()); 099 } 100 if (getExpressionValue() != null) { 101 sb.append(getExpressionValue().toString()); 102 } 103 if (getPredicate() == null && getExpressionValue() == null && getExpression() != null) { 104 sb.append(getExpression()); 105 } 106 if (getLanguage() != null) { 107 sb.append("}"); 108 } 109 return sb.toString(); 110 } 111 112 public Object evaluate(Exchange exchange) { 113 return evaluate(exchange, Object.class); 114 } 115 116 public <T> T evaluate(Exchange exchange, Class<T> type) { 117 if (expressionValue == null) { 118 expressionValue = createExpression(exchange.getContext()); 119 } 120 ObjectHelper.notNull(expressionValue, "expressionValue"); 121 return expressionValue.evaluate(exchange, type); 122 } 123 124 public void assertMatches(String text, Exchange exchange) throws AssertionError { 125 if (!matches(exchange)) { 126 throw new AssertionError(text + getExpression() + " for exchange: " + exchange); 127 } 128 } 129 130 public boolean matches(Exchange exchange) { 131 if (predicate == null) { 132 predicate = createPredicate(exchange.getContext()); 133 } 134 ObjectHelper.notNull(predicate, "predicate"); 135 return predicate.matches(exchange); 136 } 137 138 public String getLanguage() { 139 return ""; 140 } 141 142 public final Predicate createPredicate(RouteContext routeContext) { 143 return createPredicate(routeContext.getCamelContext()); 144 } 145 146 public Predicate createPredicate(CamelContext camelContext) { 147 if (predicate == null) { 148 if (getExpressionType() != null) { 149 predicate = getExpressionType().createPredicate(camelContext); 150 } else if (getExpressionValue() != null) { 151 predicate = new ExpressionToPredicateAdapter(getExpressionValue()); 152 } else if (getExpression() != null) { 153 ObjectHelper.notNull("language", getLanguage()); 154 Language language = camelContext.resolveLanguage(getLanguage()); 155 String exp = getExpression(); 156 // trim if configured to trim 157 if (exp != null && isTrim()) { 158 exp = exp.trim(); 159 } 160 predicate = language.createPredicate(exp); 161 configurePredicate(camelContext, predicate); 162 } 163 } 164 return predicate; 165 } 166 167 public final Expression createExpression(RouteContext routeContext) { 168 return createExpression(routeContext.getCamelContext()); 169 } 170 171 public Expression createExpression(CamelContext camelContext) { 172 if (getExpressionValue() == null) { 173 if (getExpressionType() != null) { 174 setExpressionValue(getExpressionType().createExpression(camelContext)); 175 } else if (getExpression() != null) { 176 ObjectHelper.notNull("language", getLanguage()); 177 Language language = camelContext.resolveLanguage(getLanguage()); 178 String exp = getExpression(); 179 // trim if configured to trim 180 if (exp != null && isTrim()) { 181 exp = exp.trim(); 182 } 183 setExpressionValue(language.createExpression(exp)); 184 configureExpression(camelContext, getExpressionValue()); 185 } 186 } 187 return getExpressionValue(); 188 } 189 190 public String getExpression() { 191 return expression; 192 } 193 194 @Required 195 public void setExpression(String expression) { 196 this.expression = expression; 197 } 198 199 /** 200 * Gets the value of the id property. 201 */ 202 public String getId() { 203 return id; 204 } 205 206 /** 207 * Sets the value of the id property. 208 */ 209 public void setId(String value) { 210 this.id = value; 211 } 212 213 public Predicate getPredicate() { 214 return predicate; 215 } 216 217 public Expression getExpressionValue() { 218 return expressionValue; 219 } 220 221 protected void setExpressionValue(Expression expressionValue) { 222 this.expressionValue = expressionValue; 223 } 224 225 public ExpressionDefinition getExpressionType() { 226 return expressionType; 227 } 228 229 public Boolean getTrim() { 230 return trim; 231 } 232 233 public void setTrim(Boolean trim) { 234 this.trim = trim; 235 } 236 237 public boolean isTrim() { 238 // trim by default 239 return trim == null || trim; 240 } 241 242 /** 243 * Returns some descriptive text to describe this node 244 */ 245 public String getLabel() { 246 Predicate predicate = getPredicate(); 247 if (predicate != null) { 248 return predicate.toString(); 249 } 250 Expression expressionValue = getExpressionValue(); 251 if (expressionValue != null) { 252 return expressionValue.toString(); 253 } 254 255 String exp = getExpression(); 256 return exp != null ? exp : ""; 257 } 258 259 /** 260 * Allows derived classes to set a lazily created expressionType instance 261 * such as if using the {@link org.apache.camel.builder.ExpressionClause} 262 */ 263 protected void setExpressionType(ExpressionDefinition expressionType) { 264 this.expressionType = expressionType; 265 } 266 267 protected void configurePredicate(CamelContext camelContext, Predicate predicate) { 268 } 269 270 protected void configureExpression(CamelContext camelContext, Expression expression) { 271 } 272 273 /** 274 * Sets a named property on the object instance using introspection 275 */ 276 protected void setProperty(Object bean, String name, Object value) { 277 try { 278 IntrospectionSupport.setProperty(bean, name, value); 279 } catch (Exception e) { 280 throw new IllegalArgumentException("Failed to set property " + name + " on " + bean 281 + ". Reason: " + e, e); 282 } 283 } 284 }