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.ArrayList;
020    import java.util.List;
021    import java.util.concurrent.BlockingQueue;
022    import java.util.concurrent.ThreadPoolExecutor;
023    
024    import javax.xml.bind.annotation.XmlAccessType;
025    import javax.xml.bind.annotation.XmlAccessorType;
026    import javax.xml.bind.annotation.XmlAttribute;
027    import javax.xml.bind.annotation.XmlElementRef;
028    import javax.xml.bind.annotation.XmlRootElement;
029    import javax.xml.bind.annotation.XmlTransient;
030    
031    import org.apache.camel.Processor;
032    import org.apache.camel.builder.ErrorHandlerBuilder;
033    import org.apache.camel.processor.Pipeline;
034    import org.apache.camel.processor.ThreadProcessor;
035    import org.apache.camel.spi.RouteContext;
036    
037    /**
038     * Represents an XML <thread/> element
039     *
040     * @version $Revision: 51015 $
041     */
042    @XmlRootElement(name = "thread")
043    @XmlAccessorType(XmlAccessType.FIELD)
044    public class ThreadType extends ProcessorType<ProcessorType> {
045        @XmlAttribute(required = false)
046        private Integer coreSize = 1;
047        @XmlAttribute(required = false)
048        private Boolean daemon = Boolean.TRUE;
049        @XmlAttribute(required = false)
050        private Long keepAliveTime;
051        @XmlAttribute(required = false)
052        private Integer maxSize = 1;
053        @XmlAttribute(required = false)
054        private String name = "Thread Processor";
055        @XmlAttribute(required = false)
056        private Integer priority = Thread.NORM_PRIORITY;
057        @XmlAttribute(required = false)
058        private Long stackSize;
059        @XmlElementRef
060        private List<ProcessorType<?>> outputs = new ArrayList<ProcessorType<?>>();
061        @XmlTransient
062        private BlockingQueue<Runnable> taskQueue;
063        @XmlTransient
064        private ThreadGroup threadGroup;
065        @XmlTransient
066        private ThreadPoolExecutor executor;
067    
068        public ThreadType() {
069        }
070    
071        public ThreadType(int coreSize) {
072            this.coreSize = coreSize;
073            this.maxSize = coreSize;
074        }
075    
076        public ThreadType(ThreadPoolExecutor executor) {
077            this.executor = executor;
078        }
079    
080        @Override
081        public List<ProcessorType<?>> getOutputs() {
082            return outputs;
083        }
084    
085        @Override
086        public String toString() {
087            return "Thread[" + getLabel() + "]";
088        }
089    
090        @Override
091        public String getShortName() {
092            return "thread";
093        }
094    
095        @Override
096        public String getLabel() {
097            return "coreSize=" + coreSize;
098        }
099    
100        @Override
101        public Processor createProcessor(RouteContext routeContext) throws Exception {
102            ThreadProcessor thread = new ThreadProcessor();
103            thread.setExecutor(executor);
104            if (coreSize != null) {
105                thread.setCoreSize(coreSize);
106            }
107            if (daemon != null) {
108                thread.setDaemon(daemon);
109            }
110            if (keepAliveTime != null) {
111                thread.setKeepAliveTime(keepAliveTime);
112            }
113            if (maxSize != null) {
114                thread.setMaxSize(maxSize);
115            }
116            thread.setName(name);
117            thread.setPriority(priority);
118            if (stackSize != null) {
119                thread.setStackSize(stackSize);
120            }
121            thread.setTaskQueue(taskQueue);
122            thread.setThreadGroup(threadGroup);
123    
124            // TODO: see if we can avoid creating so many nested pipelines
125            ArrayList<Processor> pipe = new ArrayList<Processor>(2);
126            pipe.add(thread);
127            pipe.add(createOutputsProcessor(routeContext, outputs));
128            return new Pipeline(pipe);
129        }
130    
131        @Override
132        protected void configureChild(ProcessorType output) {
133            super.configureChild(output);
134            if (isInheritErrorHandler()) {
135                output.setErrorHandlerBuilder(getErrorHandlerBuilder());
136            }
137        }
138    
139        // Fluent methods
140        // -----------------------------------------------------------------------
141        @Override
142        public ProcessorType errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
143            // do not support setting error handling on thread type as its confusing and will not be used
144            throw new IllegalArgumentException("Setting errorHandler on ThreadType is not supported."
145                + " Instead set the errorHandler on the parent.");
146        }
147    
148        public ThreadType coreSize(int coreSize) {
149            setCoreSize(coreSize);
150            return this;
151        }
152    
153        public ThreadType daemon(boolean daemon) {
154            setDaemon(daemon);
155            return this;
156        }
157    
158        public ThreadType keepAliveTime(long keepAliveTime) {
159            setKeepAliveTime(keepAliveTime);
160            return this;
161        }
162    
163        public ThreadType maxSize(int maxSize) {
164            setMaxSize(maxSize);
165            return this;
166        }
167    
168        public ThreadType name(String name) {
169            setName(name);
170            return this;
171        }
172    
173        public ThreadType priority(int priority) {
174            setPriority(priority);
175            return this;
176        }
177    
178        public ThreadType stackSize(long stackSize) {
179            setStackSize(stackSize);
180            return this;
181        }
182    
183        public ThreadType taskQueue(BlockingQueue<Runnable> taskQueue) {
184            setTaskQueue(taskQueue);
185            return this;
186        }
187    
188        public ThreadType threadGroup(ThreadGroup threadGroup) {
189            setThreadGroup(threadGroup);
190            return this;
191        }
192    
193        public ThreadType executor(ThreadPoolExecutor executor) {
194            setExecutor(executor);
195            return this;
196        }
197    
198        ///////////////////////////////////////////////////////////////////
199        //
200        // Property Accessors
201        //
202        ///////////////////////////////////////////////////////////////////
203    
204        public void setCoreSize(int coreSize) {
205            this.coreSize = coreSize;
206        }
207    
208        public void setDaemon(boolean daemon) {
209            this.daemon = daemon;
210        }
211    
212        public void setKeepAliveTime(long keepAliveTime) {
213            this.keepAliveTime = keepAliveTime;
214        }
215    
216        public void setMaxSize(int maxSize) {
217            this.maxSize = maxSize;
218        }
219    
220        public void setName(String name) {
221            this.name = name;
222        }
223    
224        public void setPriority(int priority) {
225            this.priority = priority;
226        }
227    
228        public void setStackSize(long stackSize) {
229            this.stackSize = stackSize;
230        }
231    
232        public void setTaskQueue(BlockingQueue<Runnable> taskQueue) {
233            this.taskQueue = taskQueue;
234        }
235    
236        public void setThreadGroup(ThreadGroup threadGroup) {
237            this.threadGroup = threadGroup;
238        }
239    
240        public ThreadPoolExecutor getExecutor() {
241            return executor;
242        }
243    
244        public void setExecutor(ThreadPoolExecutor executor) {
245            this.executor = executor;
246        }
247    }