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.Collections;
021    import java.util.List;
022    
023    import javax.xml.bind.annotation.XmlAccessType;
024    import javax.xml.bind.annotation.XmlAccessorType;
025    import javax.xml.bind.annotation.XmlElement;
026    import javax.xml.bind.annotation.XmlElementRef;
027    import javax.xml.bind.annotation.XmlRootElement;
028    
029    import org.apache.camel.Predicate;
030    import org.apache.camel.Processor;
031    import org.apache.camel.builder.ExpressionClause;
032    import org.apache.camel.processor.ChoiceProcessor;
033    import org.apache.camel.processor.FilterProcessor;
034    import org.apache.camel.spi.RouteContext;
035    import org.apache.camel.util.CollectionStringBuffer;
036    import org.apache.commons.logging.Log;
037    import org.apache.commons.logging.LogFactory;
038    
039    /**
040     * Represents an XML <choice/> element
041     *
042     * @version $Revision: 750806 $
043     */
044    @XmlRootElement(name = "choice")
045    @XmlAccessorType(XmlAccessType.FIELD)
046    public class ChoiceDefinition extends ProcessorDefinition<ChoiceDefinition> {
047        private static final transient Log LOG = LogFactory.getLog(ChoiceDefinition.class);
048        
049        @XmlElementRef
050        private List<WhenDefinition> whenClauses = new ArrayList<WhenDefinition>();
051        @XmlElement(required = false)
052        private OtherwiseDefinition otherwise;
053    
054        @Override
055        public String toString() {
056            if (getOtherwise() != null) {
057                return "Choice[" + getWhenClauses() + " " + getOtherwise() + "]";
058            } else {
059                return "Choice[" + getWhenClauses() + "]";
060    
061            }
062        }
063        @Override
064        public String getShortName() {
065            return "choice";
066        }
067               
068        @Override
069        public Processor createProcessor(RouteContext routeContext) throws Exception {
070            List<FilterProcessor> filters = new ArrayList<FilterProcessor>();
071            for (WhenDefinition whenClaus : whenClauses) {
072                filters.add(whenClaus.createProcessor(routeContext));
073            }
074            Processor otherwiseProcessor = null;
075            if (otherwise != null) {
076                otherwiseProcessor = otherwise.createProcessor(routeContext);
077            } else {
078                LOG.warn("No otherwise clause was specified for this choice block: " + this + ", any unmatched exchanges will be dropped.");
079            }
080            return new ChoiceProcessor(filters, otherwiseProcessor);
081        }
082    
083        // Fluent API
084        // -------------------------------------------------------------------------
085        /**
086         * Sets the predicate for the when node
087         *
088         * @param predicate  the predicate
089         * @return the builder
090         */
091        public ChoiceDefinition when(Predicate predicate) {
092            getWhenClauses().add(new WhenDefinition(predicate));
093            return this;
094        }
095    
096        /**
097         * Creates an expression for the when node
098         *
099         * @return expression to be used as builder to configure the when node
100         */
101        public ExpressionClause<ChoiceDefinition> when() {
102            WhenDefinition when = new WhenDefinition();
103            getWhenClauses().add(when);
104            ExpressionClause<ChoiceDefinition> clause = new ExpressionClause<ChoiceDefinition>(this);
105            when.setExpression(clause);
106            return clause;
107        }
108    
109        /**
110         * Sets the otherwise node
111         * 
112         * @return the builder
113         */
114        public ChoiceDefinition otherwise() {
115            OtherwiseDefinition answer = new OtherwiseDefinition();
116            setOtherwise(answer);
117            return this;
118        }
119    
120        // Properties
121        // -------------------------------------------------------------------------
122    
123        @Override
124        public String getLabel() {
125            CollectionStringBuffer buffer = new CollectionStringBuffer();
126            List<WhenDefinition> list = getWhenClauses();
127            for (WhenDefinition whenType : list) {
128                buffer.append(whenType.getLabel());
129            }
130            return buffer.toString();
131        }
132    
133        public List<WhenDefinition> getWhenClauses() {
134            return whenClauses;
135        }
136    
137        public void setWhenClauses(List<WhenDefinition> whenClauses) {
138            this.whenClauses = whenClauses;
139        }
140    
141        @SuppressWarnings("unchecked")
142        public List<ProcessorDefinition> getOutputs() {
143            if (otherwise != null) {
144                return otherwise.getOutputs();
145            } else if (whenClauses.isEmpty()) {
146                return Collections.EMPTY_LIST;
147            } else {
148                WhenDefinition when = whenClauses.get(whenClauses.size() - 1);
149                return when.getOutputs();
150            }
151        }
152    
153        public OtherwiseDefinition getOtherwise() {
154            return otherwise;
155        }
156    
157        public void setOtherwise(OtherwiseDefinition otherwise) {
158            this.otherwise = otherwise;
159        }
160    }