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 }