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.processor.interceptor;
018    
019    import java.util.List;
020    
021    import org.apache.camel.Exchange;
022    import org.apache.camel.Message;
023    import org.apache.camel.Predicate;
024    import org.apache.camel.Processor;
025    import org.apache.camel.model.ProcessorType;
026    import org.apache.camel.processor.DelegateProcessor;
027    
028    /**
029     * An interceptor for debugging and tracing routes
030     *
031     * @deprecated will be removed in Camel 2.0
032     * @version $Revision: 14069 $
033     */
034    public class DebugInterceptor extends DelegateProcessor {
035        private final ProcessorType node;
036        private final List<Exchange> exchanges;
037        private final List<ExceptionEvent> exceptions;
038        private Predicate traceFilter;
039        private Breakpoint breakpoint = new Breakpoint();
040        private boolean traceExceptions = true;
041        private boolean enabled = true;
042    
043        public DebugInterceptor(ProcessorType node, Processor target, List<Exchange> exchanges, List<ExceptionEvent> exceptions) {
044            super(target);
045            this.node = node;
046            this.exchanges = exchanges;
047            this.exceptions = exceptions;
048        }
049    
050        @Override
051        public String toString() {
052            return "DebugInterceptor[" + node + "]";
053        }
054    
055        public void process(Exchange exchange) throws Exception {
056            if (isEnabled()) {
057                checkForBreakpoint(exchange);
058                addTraceExchange(exchange);
059            }
060            try {
061                super.proceed(exchange);
062            } catch (Exception e) {
063                onException(exchange, e);
064                throw e;
065            } catch (Error e) {
066                onException(exchange, e);
067                throw e;
068            }
069        }
070    
071        public ProcessorType getNode() {
072            return node;
073        }
074    
075        public boolean isEnabled() {
076            return enabled;
077        }
078    
079        public void setEnabled(boolean flag) {
080            enabled = flag;
081        }
082    
083        public List<Exchange> getExchanges() {
084            return exchanges;
085        }
086    
087        public List<ExceptionEvent> getExceptions() {
088            return exceptions;
089        }
090    
091        public Breakpoint getBreakpoint() {
092            return breakpoint;
093        }
094    
095        public Predicate getTraceFilter() {
096            return traceFilter;
097        }
098    
099        public void setTraceFilter(Predicate traceFilter) {
100            this.traceFilter = traceFilter;
101        }
102    
103        public boolean isTraceExceptions() {
104            return traceExceptions;
105        }
106    
107        public void setTraceExceptions(boolean traceExceptions) {
108            this.traceExceptions = traceExceptions;
109        }
110    
111        /**
112         * Stategy method to wait for a breakpoint if one is set
113         */
114        protected void checkForBreakpoint(Exchange exchange) {
115            breakpoint.waitForBreakpoint(exchange);
116        }
117    
118        /**
119         * Fired when an exception is thrown when processing the underlying processor
120         */
121        protected void onException(Exchange exchange, Throwable e) {
122            if (shouldTraceExceptionEvents(exchange, e))  {
123                exceptions.add(new ExceptionEvent(this, exchange, e));
124            }
125    
126        }
127    
128        private boolean shouldTraceExceptionEvents(Exchange exchange, Throwable e) {
129            return isTraceExceptions() && isEnabled();
130        }
131    
132        /**
133         * Strategy method to store the exchange in a trace log if it is enabled
134         */
135        protected void addTraceExchange(Exchange exchange) {
136            if (shouldTraceExchange(exchange)) {
137                exchanges.add(copyExchange(exchange));
138            }
139        }
140    
141        protected Exchange copyExchange(Exchange previousExchange) {
142            Exchange answer = previousExchange.newInstance();
143            answer.getProperties().putAll(previousExchange.getProperties());
144            answer.getIn().copyFrom(previousExchange.getIn());
145    
146            // only copy the out if its defined
147            Message previousOut = previousExchange.getOut(false);
148            if (previousOut != null) {
149                answer.getOut().copyFrom(previousOut);
150            }
151            return answer;
152        }
153    
154        /**
155         * Returns true if the given exchange should be logged in the trace list
156         */
157        protected boolean shouldTraceExchange(Exchange exchange) {
158            return traceFilter == null || traceFilter.matches(exchange);
159        }
160    }