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.activemq.transport;
018
019import java.io.IOException;
020
021import org.slf4j.Logger;
022
023/**
024 * This TransportFilter implementation writes output to a log
025 * as it intercepts commands / events before sending them to the
026 * following layer in the Transport stack.
027 * 
028 * @author David Martin Clavo david(dot)martin(dot)clavo(at)gmail.com
029 * 
030 */
031public class TransportLogger extends TransportFilter {
032
033    private final Logger log;
034    private boolean logging;
035    private final LogWriter logWriter;
036    private TransportLoggerView view;
037
038    public TransportLogger(Transport next, Logger log, boolean startLogging, LogWriter logWriter) {
039        // Changed constructor to pass the implementation of the LogWriter interface
040        // that will be used to write the messages.
041        super(next);
042        this.log = log;
043        this.logging = startLogging;
044        this.logWriter = logWriter;
045    }
046
047    /**
048     * Returns true if logging is activated for this TransportLogger, false otherwise.
049     * @return true if logging is activated for this TransportLogger, false otherwise.
050     */
051    public boolean isLogging() {
052        return logging;
053    }
054
055    /**
056     * Sets if logging should be activated for this TransportLogger.
057     * @param logging true to activate logging, false to deactivate.
058     */
059    public void setLogging(boolean logging) {
060        this.logging = logging;
061    } 
062
063    public Object request(Object command) throws IOException {
064        // Changed this method to use a LogWriter object to actually 
065        // print the messages to the log, and only in case of logging 
066        // being active, instead of logging the message directly.
067        if (logging)
068            logWriter.logRequest(log, command);
069        Object rc = super.request(command);
070        if (logging)
071            logWriter.logResponse(log, command);
072        return rc;
073    }
074
075    public Object request(Object command, int timeout) throws IOException {
076        // Changed this method to use a LogWriter object to actually 
077        // print the messages to the log, and only in case of logging 
078        // being active, instead of logging the message directly.
079        if (logging)
080            logWriter.logRequest(log, command);
081        Object rc = super.request(command, timeout);
082        if (logging)
083            logWriter.logResponse(log, command);
084        return rc;
085    }
086
087    public FutureResponse asyncRequest(Object command, ResponseCallback responseCallback) throws IOException {
088        // Changed this method to use a LogWriter object to actually 
089        // print the messages to the log, and only in case of logging 
090        // being active, instead of logging the message directly.
091        if (logging)
092            logWriter.logAsyncRequest(log, command);
093        FutureResponse rc = next.asyncRequest(command, responseCallback);
094        return rc;
095    }
096
097    public void oneway(Object command) throws IOException {
098        // Changed this method to use a LogWriter object to actually 
099        // print the messages to the log, and only in case of logging 
100        // being active, instead of logging the message directly.
101        if( logging && log.isDebugEnabled() ) {
102            logWriter.logOneWay(log, command);
103        }
104        next.oneway(command);
105    }
106
107    public void onCommand(Object command) {
108        // Changed this method to use a LogWriter object to actually 
109        // print the messages to the log, and only in case of logging 
110        // being active, instead of logging the message directly.
111        if( logging && log.isDebugEnabled() ) {
112            logWriter.logReceivedCommand(log, command);
113        }
114        getTransportListener().onCommand(command);
115    }
116
117    public void onException(IOException error) {
118        // Changed this method to use a LogWriter object to actually 
119        // print the messages to the log, and only in case of logging 
120        // being active, instead of logging the message directly.
121        if( logging && log.isDebugEnabled() ) {
122            logWriter.logReceivedException(log, error);
123        }
124        getTransportListener().onException(error);
125    }
126
127    /**
128     * Gets the associated MBean for this TransportLogger.
129     * @return the associated MBean for this TransportLogger.
130     */
131    public TransportLoggerView getView() {
132        return view;
133    }
134
135    /**
136     * Sets the associated MBean for this TransportLogger.
137     * @param view the associated MBean for this TransportLogger.
138     */
139    public void setView(TransportLoggerView view) {
140        this.view = view;
141    }
142
143
144    public String toString() {
145        return next.toString();
146    }
147
148    @Override
149    public void stop() throws Exception {
150        super.stop();
151        if (view != null) {
152            view.unregister();
153        }
154    }
155}