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.impl;
018    
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    import java.util.Stack;
025    import java.util.concurrent.atomic.AtomicInteger;
026    
027    import org.apache.camel.RouteNode;
028    import org.apache.camel.model.ProcessorDefinition;
029    import org.apache.camel.spi.TracedRouteNodes;
030    
031    /**
032     * @version 
033     */
034    public class DefaultTracedRouteNodes implements TracedRouteNodes {
035        private final Stack<List<RouteNode>> routeNodes = new Stack<List<RouteNode>>();
036        private final Map<ProcessorDefinition<?>, AtomicInteger> nodeCounter = new HashMap<ProcessorDefinition<?>, AtomicInteger>();
037    
038        public DefaultTracedRouteNodes() {
039            // create an empty list to start with
040            routeNodes.push(new ArrayList<RouteNode>());
041        }
042    
043        public void addTraced(RouteNode entry) {
044            List<RouteNode> list = routeNodes.isEmpty() ? null : routeNodes.peek();
045            if (list == null) {
046                list = new ArrayList<RouteNode>();
047                routeNodes.push(list);
048            }
049            list.add(entry);
050        }
051    
052        public RouteNode getLastNode() {
053            List<RouteNode> list = routeNodes.isEmpty() ? null : routeNodes.peek();
054            if (list == null || list.isEmpty()) {
055                return null;
056            }
057            return list.get(list.size() - 1);
058        }
059    
060        public RouteNode getSecondLastNode() {
061            List<RouteNode> list = routeNodes.isEmpty() ? null : routeNodes.peek();
062            if (list == null || list.isEmpty() || list.size() == 1) {
063                return null;
064            }
065            return list.get(list.size() - 2);
066        }
067    
068        public List<RouteNode> getNodes() {
069            List<RouteNode> answer = new ArrayList<RouteNode>();
070            for (List<RouteNode> list : routeNodes) {
071                answer.addAll(list);
072            }
073            return Collections.unmodifiableList(answer);
074        }
075    
076        public void popBlock() {
077            if (!routeNodes.isEmpty()) {
078                routeNodes.pop();
079            }
080        }
081    
082        public void pushBlock() {
083            // push a new block and add the last node as starting point
084            RouteNode last = getLastNode();
085            routeNodes.push(new ArrayList<RouteNode>());
086            if (last != null) {
087                addTraced(last);
088            }
089        }
090    
091        public void clear() {
092            routeNodes.clear();
093        }
094    
095        public int getAndIncrementCounter(ProcessorDefinition<?> node) {
096            AtomicInteger count = nodeCounter.get(node);
097            if (count == null) {
098                count = new AtomicInteger();
099                nodeCounter.put(node, count);
100            }
101            return count.getAndIncrement();
102        }
103    
104    }