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