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