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.model; 018 019import java.util.ArrayList; 020import java.util.List; 021import javax.xml.bind.annotation.XmlAccessType; 022import javax.xml.bind.annotation.XmlAccessorType; 023import javax.xml.bind.annotation.XmlElementRef; 024 025import org.apache.camel.Expression; 026import org.apache.camel.Predicate; 027import org.apache.camel.Processor; 028import org.apache.camel.builder.ExpressionClause; 029import org.apache.camel.model.language.ExpressionDefinition; 030import org.apache.camel.processor.FilterProcessor; 031import org.apache.camel.spi.RouteContext; 032 033/** 034 * A base class for nodes which contain an expression and a number of outputs 035 * 036 * @version 037 */ 038@XmlAccessorType(XmlAccessType.FIELD) 039public abstract class ExpressionNode extends ProcessorDefinition<ExpressionNode> { 040 @XmlElementRef 041 private ExpressionDefinition expression; 042 @XmlElementRef 043 private List<ProcessorDefinition<?>> outputs = new ArrayList<ProcessorDefinition<?>>(); 044 045 public ExpressionNode() { 046 } 047 048 public ExpressionNode(ExpressionDefinition expression) { 049 this.expression = expression; 050 } 051 052 public ExpressionNode(Expression expression) { 053 if (expression != null) { 054 setExpression(ExpressionNodeHelper.toExpressionDefinition(expression)); 055 } 056 } 057 058 public ExpressionNode(Predicate predicate) { 059 if (predicate != null) { 060 setExpression(ExpressionNodeHelper.toExpressionDefinition(predicate)); 061 } 062 } 063 064 public ExpressionDefinition getExpression() { 065 return expression; 066 } 067 068 public void setExpression(ExpressionDefinition expression) { 069 // favour using the helper to set the expression as it can unwrap some unwanted builders when using Java DSL 070 if (expression instanceof Expression) { 071 this.expression = ExpressionNodeHelper.toExpressionDefinition((Expression) expression); 072 } else if (expression instanceof Predicate) { 073 this.expression = ExpressionNodeHelper.toExpressionDefinition((Predicate) expression); 074 } else { 075 this.expression = expression; 076 } 077 } 078 079 @Override 080 public List<ProcessorDefinition<?>> getOutputs() { 081 return outputs; 082 } 083 084 public void setOutputs(List<ProcessorDefinition<?>> outputs) { 085 this.outputs = outputs; 086 } 087 088 @Override 089 public boolean isOutputSupported() { 090 return true; 091 } 092 093 @Override 094 public String getLabel() { 095 if (getExpression() == null) { 096 return ""; 097 } 098 return getExpression().getLabel(); 099 } 100 101 /** 102 * Creates the {@link FilterProcessor} from the expression node. 103 * 104 * @param routeContext the route context 105 * @return the created {@link FilterProcessor} 106 * @throws Exception is thrown if error creating the processor 107 */ 108 protected FilterProcessor createFilterProcessor(RouteContext routeContext) throws Exception { 109 Processor childProcessor = createOutputsProcessor(routeContext); 110 return new FilterProcessor(createPredicate(routeContext), childProcessor); 111 } 112 113 /** 114 * Creates the {@link Predicate} from the expression node. 115 * 116 * @param routeContext the route context 117 * @return the created predicate 118 */ 119 protected Predicate createPredicate(RouteContext routeContext) { 120 return getExpression().createPredicate(routeContext); 121 } 122 123 @Override 124 public void configureChild(ProcessorDefinition<?> output) { 125 // reuse the logic from pre create processor 126 preCreateProcessor(); 127 } 128 129 @Override 130 protected void preCreateProcessor() { 131 Expression exp = expression; 132 if (expression != null && expression.getExpressionValue() != null) { 133 exp = expression.getExpressionValue(); 134 } 135 136 if (exp instanceof ExpressionClause) { 137 ExpressionClause<?> clause = (ExpressionClause<?>) exp; 138 if (clause.getExpressionType() != null) { 139 // if using the Java DSL then the expression may have been set using the 140 // ExpressionClause which is a fancy builder to define expressions and predicates 141 // using fluent builders in the DSL. However we need afterwards a callback to 142 // reset the expression to the expression type the ExpressionClause did build for us 143 expression = clause.getExpressionType(); 144 } 145 } 146 147 if (expression != null && expression.getExpression() == null) { 148 // use toString from predicate or expression so we have some information to show in the route model 149 if (expression.getPredicate() != null) { 150 expression.setExpression(expression.getPredicate().toString()); 151 } else if (expression.getExpressionValue() != null) { 152 expression.setExpression(expression.getExpressionValue().toString()); 153 } 154 } 155 } 156}