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 */ 017package org.apache.camel.builder; 018 019import org.apache.camel.CamelContext; 020import org.apache.camel.CamelExecutionException; 021import org.apache.camel.Exchange; 022import org.apache.camel.Expression; 023import org.apache.camel.Predicate; 024import org.apache.camel.spi.ExpressionResultTypeAware; 025import org.apache.camel.spi.Language; 026import org.apache.camel.spi.PropertyConfigurer; 027import org.apache.camel.support.PredicateToExpressionAdapter; 028import org.apache.camel.support.ScriptHelper; 029import org.apache.camel.support.component.PropertyConfigurerSupport; 030 031/** 032 * Creates an {@link org.apache.camel.language.simple.Simple} language builder. 033 * <p/> 034 * This builder is available in the Java DSL from the {@link RouteBuilder} which 035 * means that using simple language for {@link Expression}s or 036 * {@link Predicate}s is very easy with the help of this builder. 037 */ 038public class SimpleBuilder implements Predicate, Expression, ExpressionResultTypeAware, PropertyConfigurer { 039 040 private final String text; 041 private Class<?> resultType; 042 // cache the expression/predicate 043 private volatile Expression expression; 044 private volatile Predicate predicate; 045 046 public SimpleBuilder(String text) { 047 this.text = text; 048 } 049 050 public static SimpleBuilder simple(String text) { 051 return new SimpleBuilder(text); 052 } 053 054 public static SimpleBuilder simple(String text, Class<?> resultType) { 055 SimpleBuilder answer = simple(text); 056 answer.setResultType(resultType); 057 return answer; 058 } 059 060 public static SimpleBuilder simpleF(String formatText, Object... values) { 061 return simple(String.format(formatText, values)); 062 } 063 064 public static SimpleBuilder simpleF(String formatText, Class<?> resultType, Object... values) { 065 return simple(String.format(formatText, values), resultType); 066 } 067 068 @Override 069 public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) { 070 if (target != this) { 071 throw new IllegalStateException("Can only configure our own instance !"); 072 } 073 switch (ignoreCase ? name.toLowerCase() : name) { 074 case "resulttype": 075 case "resultType": 076 setResultType(PropertyConfigurerSupport.property(camelContext, Class.class, value)); return true; 077 default: 078 return false; 079 } 080 } 081 082 public String getText() { 083 return text; 084 } 085 086 @Override 087 public String getExpressionText() { 088 return getText(); 089 } 090 091 @Override 092 public Class<?> getResultType() { 093 return resultType; 094 } 095 096 public void setResultType(Class<?> resultType) { 097 this.resultType = resultType; 098 } 099 100 public SimpleBuilder resultType(Class<?> resultType) { 101 setResultType(resultType); 102 return this; 103 } 104 105 @Override 106 public void init(CamelContext context) { 107 } 108 109 @Override 110 public boolean matches(Exchange exchange) { 111 if (predicate == null) { 112 predicate = createPredicate(exchange.getContext()); 113 } 114 return predicate.matches(exchange); 115 } 116 117 @Override 118 public <T> T evaluate(Exchange exchange, Class<T> type) { 119 if (expression == null) { 120 expression = createExpression(exchange.getContext()); 121 } 122 return expression.evaluate(exchange, type); 123 } 124 125 public Predicate createPredicate(CamelContext context) { 126 try { 127 Language simple = context.resolveLanguage("simple"); 128 // resolve property placeholders 129 String resolve = context.resolvePropertyPlaceholders(text); 130 // and optional it be refer to an external script on the file/classpath 131 if (ScriptHelper.hasExternalScript(resolve)) { 132 return new Predicate() { 133 @Override 134 public boolean matches(Exchange exchange) { 135 String r = ScriptHelper.resolveOptionalExternalScript(context, exchange, resolve); 136 return simple.createPredicate(r).matches(exchange); 137 } 138 @Override 139 public String toString() { 140 return text; 141 } 142 }; 143 } else { 144 Predicate pred = simple.createPredicate(resolve); 145 pred.init(context); 146 return pred; 147 } 148 } catch (Exception e) { 149 throw CamelExecutionException.wrapCamelExecutionException(null, e); 150 } 151 } 152 153 public Expression createExpression(CamelContext context) { 154 if (resultType == Boolean.class || resultType == boolean.class) { 155 // if its a boolean as result then its a predicate 156 Predicate predicate = createPredicate(context); 157 return PredicateToExpressionAdapter.toExpression(predicate); 158 } 159 try { 160 // resolve property placeholders 161 Language simple = context.resolveLanguage("simple"); 162 String resolve = context.resolvePropertyPlaceholders(text); 163 Expression exp; 164 // and optional it be refer to an external script on the file/classpath 165 if (ScriptHelper.hasExternalScript(resolve)) { 166 exp = new Expression() { 167 @Override 168 public <T> T evaluate(Exchange exchange, Class<T> type) { 169 String r = ScriptHelper.resolveOptionalExternalScript(context, exchange, resolve); 170 Expression exp = simple.createExpression(r); 171 return exp.evaluate(exchange, type); 172 } 173 @Override 174 public String toString() { 175 return text; 176 } 177 }; 178 } else { 179 exp = simple.createExpression(resolve); 180 exp.init(context); 181 } 182 if (resultType != null) { 183 exp = ExpressionBuilder.convertToExpression(exp, resultType); 184 } 185 return exp; 186 } catch (Exception e) { 187 throw CamelExecutionException.wrapCamelExecutionException(null, e); 188 } 189 } 190 191 @Override 192 public String toString() { 193 return "Simple: " + text; 194 } 195 196}