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