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     */
017    package org.apache.camel.model;
018    
019    import java.util.Collections;
020    import java.util.List;
021    import java.util.concurrent.ExecutorService;
022    import javax.xml.bind.annotation.XmlAccessType;
023    import javax.xml.bind.annotation.XmlAccessorType;
024    import javax.xml.bind.annotation.XmlAttribute;
025    import javax.xml.bind.annotation.XmlRootElement;
026    import javax.xml.bind.annotation.XmlTransient;
027    
028    import org.apache.camel.Expression;
029    import org.apache.camel.Processor;
030    import org.apache.camel.model.language.ExpressionDefinition;
031    import org.apache.camel.processor.RecipientList;
032    import org.apache.camel.processor.aggregate.AggregationStrategy;
033    import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
034    import org.apache.camel.spi.RouteContext;
035    import org.apache.camel.util.concurrent.ExecutorServiceHelper;
036    
037    /**
038     * Represents an XML <recipientList/> element
039     *
040     * @version $Revision: 887262 $
041     */
042    @XmlRootElement(name = "recipientList")
043    @XmlAccessorType(XmlAccessType.FIELD)
044    public class RecipientListDefinition extends ExpressionNode {
045    
046        @XmlTransient
047        private AggregationStrategy aggregationStrategy;
048        @XmlTransient
049        private ExecutorService executorService;
050        @XmlAttribute(required = false)
051        private String delimiter;
052        @XmlAttribute(required = false)
053        private Boolean parallelProcessing;
054        @XmlAttribute(required = false)
055        private String strategyRef;
056        @XmlAttribute(required = false)
057        private String executorServiceRef;
058        @XmlAttribute(required = false)
059        private Boolean stopOnException;
060    
061        public RecipientListDefinition() {
062        }
063    
064        public RecipientListDefinition(ExpressionDefinition expression) {
065            super(expression);
066        }
067    
068        public RecipientListDefinition(Expression expression) {
069            super(expression);
070        }
071    
072        @Override
073        public String toString() {
074            return "RecipientList[" + getExpression() + "]";
075        }
076    
077        @Override
078        public String getShortName() {
079            return "recipientList";
080        }
081    
082        @Override
083        public Processor createProcessor(RouteContext routeContext) throws Exception {
084            Expression expression = getExpression().createExpression(routeContext);
085    
086            RecipientList answer;
087            if (delimiter != null) {
088                answer = new RecipientList(expression, delimiter);
089            } else {
090                answer = new RecipientList(expression);
091            }
092    
093            if (parallelProcessing != null) {
094                answer.setParallelProcessing(isParallelProcessing());
095            }
096            if (stopOnException != null) {
097                answer.setStopOnException(isStopOnException());
098            }
099            
100            answer.setAggregationStrategy(createAggregationStrategy(routeContext));
101            answer.setExecutorService(createExecutorService(routeContext));
102    
103            return answer;
104        }
105        
106        private AggregationStrategy createAggregationStrategy(RouteContext routeContext) {
107            if (aggregationStrategy == null && strategyRef != null) {
108                aggregationStrategy = routeContext.lookup(strategyRef, AggregationStrategy.class);
109            }
110            if (aggregationStrategy == null) {
111                // fallback to use latest
112                aggregationStrategy = new UseLatestAggregationStrategy();
113            }
114            return aggregationStrategy;
115        }
116    
117        private ExecutorService createExecutorService(RouteContext routeContext) {
118            if (executorService == null && executorServiceRef != null) {
119                executorService = routeContext.lookup(executorServiceRef, ExecutorService.class);
120            }
121            if (executorService == null) {
122                // fall back and use default
123                executorService = ExecutorServiceHelper.newScheduledThreadPool(10, "RecipientList", true);
124            }
125            return executorService;
126        }
127    
128        @Override
129        @SuppressWarnings("unchecked")
130        public List<ProcessorDefinition> getOutputs() {
131            return Collections.EMPTY_LIST;
132        }
133    
134        @Override
135        public void addOutput(ProcessorDefinition processorType) {
136            // add it to the parent as a recipient list does not support outputs
137            getParent().addOutput(processorType);
138        }
139    
140        // Fluent API
141        // -------------------------------------------------------------------------
142    
143        /**
144         * Set the aggregationStrategy
145         *
146         * @return the builder
147         */
148        public RecipientListDefinition aggregationStrategy(AggregationStrategy aggregationStrategy) {
149            setAggregationStrategy(aggregationStrategy);
150            return this;
151        }
152    
153        /**
154         * Doing the splitting work in parallel
155         *
156         * @return the builder
157         */
158        public RecipientListDefinition parallelProcessing() {
159            setParallelProcessing(true);
160            return this;
161        }
162    
163        /**
164         * Will now stop further processing if an exception occurred during processing of an
165         * {@link org.apache.camel.Exchange} and the caused exception will be thrown.
166         * <p/>
167         * The default behavior is to <b>not</b> stop but continue processing till the end
168         *
169         * @return the builder
170         */
171        public RecipientListDefinition stopOnException() {
172            setStopOnException(true);
173            return this;
174        }
175    
176        /**
177         * Setting the executor service for executing the sending to the recipients.
178         *
179         * @param executorService the executor service
180         * @return the builder
181         */
182        public RecipientListDefinition executorService(ExecutorService executorService) {
183            setExecutorService(executorService);
184            return this;
185        }
186    
187        // Properties
188        //-------------------------------------------------------------------------
189    
190        public String getDelimiter() {
191            return delimiter;
192        }
193    
194        public void setDelimiter(String delimiter) {
195            this.delimiter = delimiter;
196        }
197    
198        public Boolean isParallelProcessing() {
199            return parallelProcessing;
200        }
201    
202        public void setParallelProcessing(Boolean parallelProcessing) {
203            this.parallelProcessing = parallelProcessing;
204        }
205    
206        public String getStrategyRef() {
207            return strategyRef;
208        }
209    
210        public void setStrategyRef(String strategyRef) {
211            this.strategyRef = strategyRef;
212        }
213    
214        public String getExecutorServiceRef() {
215            return executorServiceRef;
216        }
217    
218        public void setExecutorServiceRef(String executorServiceRef) {
219            this.executorServiceRef = executorServiceRef;
220        }
221    
222        public Boolean isStopOnException() {
223            return stopOnException;
224        }
225    
226        public void setStopOnException(Boolean stopOnException) {
227            this.stopOnException = stopOnException;
228        }
229    
230        public AggregationStrategy getAggregationStrategy() {
231            return aggregationStrategy;
232        }
233    
234        public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
235            this.aggregationStrategy = aggregationStrategy;
236        }
237    
238        public ExecutorService getExecutorService() {
239            return executorService;
240        }
241    
242        public void setExecutorService(ExecutorService executorService) {
243            this.executorService = executorService;
244        }
245    }