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