/** * * Copyright 2014 Vyacheslav Blinov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.smackx.debugger.slf4j; import java.util.concurrent.atomic.AtomicBoolean; import org.jivesoftware.smack.AbstractXMPPConnection; import org.jivesoftware.smack.ReconnectionManager; import org.jivesoftware.smack.SmackConfiguration; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.debugger.SmackDebugger; import org.jivesoftware.smack.packet.TopLevelStreamElement; import org.jivesoftware.smack.util.ObservableReader; import org.jivesoftware.smack.util.ObservableWriter; import org.jxmpp.jid.EntityFullJid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Implementation of SmackDebugger that writes log messages using SLF4J API. * Use in conjunction with your SLF4J bindings of choice. * See SLF4J manual for more details about bindings usage. */ public class SLF4JSmackDebugger extends SmackDebugger { private static final java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger(SLF4JSmackDebugger.class.getName()); public static final String LOGGER_NAME = "SMACK"; private static final Logger logger = LoggerFactory.getLogger(LOGGER_NAME); public static final AtomicBoolean printInterpreted = new AtomicBoolean(true); public static final String SENT_TAG = "SENT"; public static final String RECEIVED_TAG = "RECV"; private final SLF4JRawXmlListener slf4JRawXmlListener = new SLF4JRawXmlListener(logger); private ObservableWriter writer; private ObservableReader reader; /** * Makes Smack use this Debugger. */ public static void enable() { SmackConfiguration.DEBUG = true; SmackConfiguration.setDefaultSmackDebuggerFactory(SLF4JDebuggerFactory.INSTANCE); } /** * Create new SLF4J Smack Debugger instance. * @param connection Smack connection to debug */ SLF4JSmackDebugger(XMPPConnection connection) { super(connection); this.writer = new ObservableWriter(writer); this.writer.addWriterListener(slf4JRawXmlListener); this.reader = new ObservableReader(Validate.notNull(reader)); this.reader.addReaderListener(slf4JRawXmlListener); final SLF4JLoggingConnectionListener loggingConnectionListener = new SLF4JLoggingConnectionListener(connection, logger); this.connection.addConnectionListener(loggingConnectionListener); if (connection instanceof AbstractXMPPConnection) { AbstractXMPPConnection abstractXmppConnection = (AbstractXMPPConnection) connection; ReconnectionManager.getInstanceFor(abstractXmppConnection).addReconnectionListener(loggingConnectionListener); } else { LOGGER.info("The connection instance " + connection + " is not an instance of AbstractXMPPConnection, thus we can not install the ReconnectionListener"); } } @Override public void outgoingStreamSink(CharSequence outgoingCharSequence) { slf4JRawXmlListener.write(outgoingCharSequence.toString()); } @Override public void incomingStreamSink(CharSequence incomingCharSequence) { slf4JRawXmlListener.read(incomingCharSequence.toString()); } @Override public void userHasLogged(EntityFullJid user) { if (logger.isDebugEnabled()) { logger.debug("({}) User logged in {}", connection.hashCode(), user.toString()); } } @Override public void onIncomingStreamElement(TopLevelStreamElement streamElement) { if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) { logger.debug("IN {}: {}", streamElement.getClass().getName(), streamElement.toXML()); } } @Override public void onOutgoingStreamElement(TopLevelStreamElement streamElement) { if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) { logger.debug("OUT {}: {}", streamElement.getClass().getName(), streamElement.toXML()); } } }