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.util;
018    
019    import java.util.ArrayList;
020    import java.util.Iterator;
021    import java.util.List;
022    
023    import org.apache.camel.model.ChoiceDefinition;
024    import org.apache.camel.model.ProcessorDefinition;
025    import org.apache.camel.model.SendDefinition;
026    import org.apache.camel.model.WhenDefinition;
027    
028    /**
029     * Helper class for ProcessorType and the other model classes.
030     */
031    public final class ProcessorDefinitionHelper {
032    
033        private ProcessorDefinitionHelper() {
034        }
035    
036        /**
037         * Looks for the given type in the list of outputs and recurring all the children as well.
038         *
039         * @param outputs  list of outputs, can be null or empty.
040         * @param type     the type to look for
041         * @return         the found definitions, or <tt>null</tt> if not found
042         */
043        public static <T> Iterator<T> filterTypeInOutputs(List<ProcessorDefinition> outputs, Class<T> type) {
044            List<T> found = new ArrayList<T>();
045            doFindType(outputs, type, found);
046            return found.iterator();
047        }
048    
049        /**
050         * Looks for the given type in the list of outputs and recurring all the children as well.
051         * Will stop at first found and return it.
052         *
053         * @param outputs  list of outputs, can be null or empty.
054         * @param type     the type to look for
055         * @return         the first found type, or <tt>null</tt> if not found
056         */
057        public static <T> T findFirstTypeInOutputs(List<ProcessorDefinition> outputs, Class<T> type) {
058            List<T> found = new ArrayList<T>();
059            doFindType(outputs, type, found);
060            if (found.isEmpty()) {
061                return null;
062            }
063            return found.iterator().next();
064        }
065    
066        @SuppressWarnings("unchecked")
067        private static void doFindType(List<ProcessorDefinition> outputs, Class<?> type, List found) {
068            if (outputs == null || outputs.isEmpty()) {
069                return;
070            }
071    
072            for (ProcessorDefinition out : outputs) {
073                if (type.isInstance(out)) {
074                    found.add(out);
075                }
076    
077                // send is much common
078                if (out instanceof SendDefinition) {
079                    SendDefinition send = (SendDefinition) out;
080                    List<ProcessorDefinition> children = send.getOutputs();
081                    doFindType(children, type, found);
082                }
083    
084                // special for choice
085                if (out instanceof ChoiceDefinition) {
086                    ChoiceDefinition choice = (ChoiceDefinition) out;
087                    for (WhenDefinition when : choice.getWhenClauses()) {
088                        List<ProcessorDefinition> children = when.getOutputs();
089                        doFindType(children, type, found);
090                    }
091    
092                    // otherwise is optional
093                    if (choice.getOtherwise() != null) {
094                        List<ProcessorDefinition> children = choice.getOtherwise().getOutputs();
095                        doFindType(children, type, found);
096                    }
097                }
098    
099                // try children as well
100                List<ProcessorDefinition> children = out.getOutputs();
101                doFindType(children, type, found);
102            }
103        }
104    
105    }