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.servicemix.components.util;
018    
019    import javax.jbi.messaging.MessageExchange;
020    import javax.jbi.messaging.MessagingException;
021    import javax.jbi.messaging.NormalizedMessage;
022    import javax.xml.transform.Source;
023    import javax.xml.transform.TransformerException;
024    
025    import org.apache.commons.logging.Log;
026    import org.apache.commons.logging.LogFactory;
027    import org.apache.servicemix.MessageExchangeListener;
028    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
029    
030    /**
031     * A simple tracing component which can be placed inside a pipeline
032     * to trace the message exchange though the component.
033     *
034     * @version $Revision: 648504 $
035     */
036    public class TraceComponent extends ComponentSupport implements MessageExchangeListener {
037    
038        private Log log = LogFactory.getLog(TraceComponent.class);
039    
040        private SourceTransformer sourceTransformer = new SourceTransformer();
041    
042        public Log getLog() {
043            return log;
044        }
045    
046        public void setLog(Log log) {
047            this.log = log;
048        }
049    
050        public SourceTransformer getSourceTransformer() {
051            return sourceTransformer;
052        }
053    
054        public void setSourceTransformer(SourceTransformer sourceTransformer) {
055            this.sourceTransformer = sourceTransformer;
056        }
057    
058        /** 
059         * Intercepts the {@link MessageExchange} to output the message and its 
060         * properties for debugging purposes. 
061         * 
062         * @param exchange A JBI {@link MessageExchange} between two endpoints
063         */
064        public void onMessageExchange(MessageExchange exchange) throws MessagingException {
065            // lets dump the incoming message  
066            NormalizedMessage message = exchange.getMessage("in");
067            if (message == null) {
068                log.warn("Received null message from exchange: " + exchange);
069            } else {
070                log.info("Exchange: " + exchange + " received IN message: " + message);
071                try {
072                    log.info("Body is: " + sourceTransformer.toString(message.getContent()));
073                } catch (TransformerException e) {
074                    log.error("Failed to turn message body into text: " + e, e);
075                }
076                outputProperties(message);
077            }
078            done(exchange);
079        }
080        
081        /**
082         * Outputs the properties on the {@link NormalizedMessage}. Properties of 
083         * type {@link Source} are transformed to a {@link String} before 
084         * being output.
085         *
086         * @param message The {@link NormalizedMessage} to be processed
087         */
088        @SuppressWarnings("unchecked")
089        protected void outputProperties(NormalizedMessage message) {
090            // Loop over all the properties on the normalized message 
091            for (Object o : message.getPropertyNames()) {
092                // NormalizedMessage API does not use generics. This interface is
093                // written in Java older than 5.0. On the basis of other methods and
094                // the default implementation of this interface we can assume that
095                // only String keys are allowed.
096                String key = (String) o;
097                try {
098                    Object contents = message.getProperty(key);
099                    // Is this the only value type that we would like to treat
100                    // differently? The default behavior is to invoke toString() on
101                    // the object.
102                    if (contents instanceof Source) {
103                        contents = getSourceTransformer().toString((Source) contents);
104                    }
105    
106                    log.info("Value for property '" + key + "' is: " + contents);
107                } catch (TransformerException e) {
108                    log.error("Failed to turn property '" + key + "' value into text: " + e, e);
109                }
110            }
111        }
112    }