View Javadoc
1   /*
2    * Copyright 2008 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *     
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.openehealth.ipf.platform.camel.core.model;
17  
18  import static org.apache.camel.util.ObjectHelper.notNull;
19  import groovy.lang.Closure;
20  
21  import groovy.transform.stc.ClosureParams;
22  import groovy.transform.stc.SimpleType;
23  import org.apache.camel.Expression;
24  import org.apache.camel.Processor;
25  import org.apache.camel.model.OutputDefinition;
26  import org.apache.camel.model.RouteDefinition;
27  import org.apache.camel.model.language.ExpressionDefinition;
28  import org.apache.camel.processor.aggregate.AggregationStrategy;
29  import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
30  import org.apache.camel.spi.Metadata;
31  import org.apache.camel.spi.RouteContext;
32  import org.openehealth.ipf.platform.camel.core.closures.DelegatingAggregationStrategy;
33  import org.openehealth.ipf.platform.camel.core.process.splitter.Splitter;
34  
35  import javax.xml.bind.annotation.*;
36  
37  /**
38   * {@link OutputDefinition} for the {@link Splitter} processor
39   * This class is needed to create a {@link Splitter} that hands on the
40   * sub exchanges to a specified processor. The {@link Splitter} requires 
41   * explicit definition of this processor because it has to send multiple 
42   * exchanges to the processor. Usually processors only send a single exchange
43   * to the next processor in the route, which is done automatically by Camel.
44   * 
45   * @author Jens Riemschneider
46   * @author Martin Krasser
47   */
48  @Metadata(label = "ipf,eip")
49  @XmlRootElement(name = "splitter")
50  @XmlType(name = "CoreSplitterDefinitionType")
51  @XmlAccessorType(XmlAccessType.FIELD)
52  public class SplitterDefinition extends OutputDefinition<RouteDefinition> {
53  
54      @XmlTransient
55      private AggregationStrategy aggregationStrategy;
56      @XmlElementRef
57      private ExpressionDefinition expressionDefinition;
58      @XmlAttribute
59      private String expressionBean;
60  
61      public SplitterDefinition() {
62      }
63  
64      /**
65       * Creates a split definition, i.e. a builder for {@link Splitter}.
66       * @param expression
67       *          The expression to be passed to the {@link Splitter} upon 
68       *          creation.
69       */
70      public SplitterDefinition(Expression expression) {
71          notNull(expression, "expression");
72          expressionDefinition = new ExpressionDefinition(expression);
73      }
74  
75      /**
76       * Creates a split type, i.e. a builder for {@link Splitter}
77       * @param expressionBean
78       *          The name of the expression bean to be passed to the {@link Splitter} 
79       *          upon creation
80       */
81      public SplitterDefinition(String expressionBean) {
82          notNull(expressionBean, "expressionBean");
83          this.expressionBean = expressionBean;
84      }
85  
86      @Override
87      public Processor createProcessor(RouteContext routeContext) throws Exception {
88          Processor childProcessor = createChildProcessor(routeContext, false);
89          if (aggregationStrategy == null) {
90              aggregationStrategy = new UseLatestAggregationStrategy();
91          }
92          if (expressionBean != null) {
93              expressionDefinition = new ExpressionDefinition(routeContext.lookup(expressionBean, Expression.class));
94          }
95          Expression expression = expressionDefinition.createExpression(routeContext);
96          Splitter splitter = createSplitterInstance(expression, childProcessor);
97          
98          splitter.aggregate(aggregationStrategy);
99          
100         return splitter;
101     }
102 
103     protected Splitter createSplitterInstance(Expression expression, Processor processor) {
104         return new Splitter(expression, processor);
105     }
106     
107     @Override
108     public String getShortName() {
109         return "split";
110     }
111    
112     @Override
113     public String toString() {
114         return "Splitter[" + expressionDefinition + " -> " + getOutputs() + "]";
115     }
116 
117     /**
118      * Defines the aggregation logic for the split results as a closure
119      * @param aggregationStrategy    
120      *          the aggregation strategy
121      */
122     public SplitterDefinition aggregationStrategy(@ClosureParams(value = SimpleType.class, options = { "org.apache.camel.Exchange", "org.apache.camel.Exchange"})
123                                                           Closure aggregationStrategy) {
124         return aggregationStrategy(new DelegatingAggregationStrategy(aggregationStrategy));
125     }
126     
127     /**
128      * Defines the aggregation logic for the split results via a strategy interface
129      * @param aggregationStrategy    
130      *          the aggregation strategy
131      */
132     public SplitterDefinition aggregationStrategy(AggregationStrategy aggregationStrategy) {
133         notNull(aggregationStrategy, "aggregationStrategy");
134         this.aggregationStrategy = aggregationStrategy;
135         return this;
136     }
137     
138 }