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