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