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.List;
020    import java.util.concurrent.ExecutorService;
021    import javax.xml.bind.annotation.XmlAccessType;
022    import javax.xml.bind.annotation.XmlAccessorType;
023    import javax.xml.bind.annotation.XmlAttribute;
024    import javax.xml.bind.annotation.XmlRootElement;
025    import javax.xml.bind.annotation.XmlTransient;
026    
027    import org.apache.camel.Processor;
028    import org.apache.camel.processor.MulticastProcessor;
029    import org.apache.camel.processor.aggregate.AggregationStrategy;
030    import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
031    import org.apache.camel.spi.RouteContext;
032    
033    /**
034     * Represents an XML <multicast/> element
035     *
036     * @version $Revision: 890241 $
037     */
038    @XmlRootElement(name = "multicast")
039    @XmlAccessorType(XmlAccessType.FIELD)
040    public class MulticastDefinition extends OutputDefinition<ProcessorDefinition> {
041        @XmlAttribute(required = false)
042        private Boolean parallelProcessing;
043        @XmlAttribute(required = false)
044        private String strategyRef;
045        @XmlTransient
046        private ExecutorService executorService;
047        @XmlAttribute(required = false)
048        private String executorServiceRef;
049        @XmlAttribute(required = false)
050        private Boolean streaming;
051        @XmlAttribute(required = false)
052        private Boolean stopOnException;
053        @XmlTransient
054        private AggregationStrategy aggregationStrategy;
055    
056    
057        @Override
058        public String toString() {
059            return "Multicast[" + getOutputs() + "]";
060        }
061    
062        @Override
063        public String getShortName() {
064            return "multicast";
065        }
066    
067        @Override
068        public Processor createProcessor(RouteContext routeContext) throws Exception {
069            return createOutputsProcessor(routeContext);
070        }
071    
072        // Fluent API
073        // -------------------------------------------------------------------------
074    
075        /**
076         * Set the multicasting aggregationStrategy
077         *
078         * @return the builder
079         */
080        public MulticastDefinition aggregationStrategy(AggregationStrategy aggregationStrategy) {
081            setAggregationStrategy(aggregationStrategy);
082            return this;
083        }
084        
085        /**
086         * Uses the {@link java.util.concurrent.ExecutorService} to do the multicasting work
087         *     
088         * @return the builder
089         */
090        public MulticastDefinition parallelProcessing() {
091            setParallelProcessing(true);
092            return this;
093        }
094        
095        /**
096         * Aggregates the responses as the are done (e.g. out of order sequence)
097         *
098         * @return the builder
099         */
100        public MulticastDefinition streaming() {
101            setStreaming(true);
102            return this;
103        }
104    
105        /**
106         * Will now stop further processing if an exception occurred during processing of an
107         * {@link org.apache.camel.Exchange} and the caused exception will be thrown.
108         * <p/>
109         * The default behavior is to <b>not</b> stop but continue processing till the end
110         *
111         * @return the builder
112         */
113        public MulticastDefinition stopOnException() {
114            setStopOnException(true);
115            return this;
116        }
117           
118        /**
119         * Setting the executor service for executing the multicasting action.
120         *
121         * @return the builder
122         */
123        public MulticastDefinition executorService(ExecutorService executorService) {
124            setExecutorService(executorService);
125            return this;
126        }    
127            
128        protected Processor createCompositeProcessor(RouteContext routeContext, List<Processor> list) throws Exception {
129            if (strategyRef != null) {
130                aggregationStrategy = routeContext.lookup(strategyRef, AggregationStrategy.class);
131            }
132            if (aggregationStrategy == null) {
133                // default to use latest aggregation strategy
134                aggregationStrategy = new UseLatestAggregationStrategy();
135            }
136            if (executorServiceRef != null) {
137                executorService = routeContext.lookup(executorServiceRef, ExecutorService.class);
138            }
139    
140            return new MulticastProcessor(list, aggregationStrategy, isParallelProcessing(), executorService,
141                                          isStreaming(), isStopOnException());
142        }
143    
144        public AggregationStrategy getAggregationStrategy() {
145            return aggregationStrategy;
146        }
147    
148        public MulticastDefinition setAggregationStrategy(AggregationStrategy aggregationStrategy) {
149            this.aggregationStrategy = aggregationStrategy;
150            return this;
151        }
152    
153        public boolean isParallelProcessing() {
154            return parallelProcessing != null ? parallelProcessing : false;
155        }
156    
157        public void setParallelProcessing(boolean parallelProcessing) {
158            this.parallelProcessing = parallelProcessing;        
159        }
160    
161        public boolean isStreaming() {
162            return streaming != null ? streaming : false;
163        }
164    
165        public void setStreaming(boolean streaming) {
166            this.streaming = streaming;
167        }
168    
169        public Boolean isStopOnException() {
170            return stopOnException != null ? stopOnException : false;
171        }
172    
173        public void setStopOnException(Boolean stopOnException) {
174            this.stopOnException = stopOnException;
175        }
176    
177        public ExecutorService getExecutorService() {
178            return executorService;
179        }
180    
181        public void setExecutorService(ExecutorService executorService) {
182            this.executorService = executorService;
183        }
184    
185    }