/******************************************************************************* * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved. * This program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tm.te.tcf.log.core.internal.listener; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; import org.eclipse.tm.tcf.core.AbstractChannel; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.te.tcf.log.core.activator.CoreBundleActivator; import org.eclipse.tm.te.tcf.log.core.interfaces.IPreferenceKeys; import org.eclipse.tm.te.tcf.log.core.interfaces.ITracing; import org.eclipse.tm.te.tcf.log.core.internal.LogManager; import org.eclipse.tm.te.tcf.log.core.internal.nls.Messages; /** * TCF logging channel trace listener manager implementation. */ public class ChannelTraceListenerManager { // The map of trace listeners per channel private final Map<IChannel, AbstractChannel.TraceListener> listeners = new HashMap<IChannel, AbstractChannel.TraceListener>(); /* * Thread save singleton instance creation. */ private static class LazyInstanceHolder { public static ChannelTraceListenerManager instance = new ChannelTraceListenerManager(); } /** * Returns the singleton instance for the manager. */ public static ChannelTraceListenerManager getInstance() { return LazyInstanceHolder.instance; } /** * Constructor. */ /* default */ ChannelTraceListenerManager() { } /** * New channel opened. Attach a channel trace listener. * * @param channel The channel. Must not be <code>null</code>. */ public void onChannelOpened(final IChannel channel) { Assert.isNotNull(channel); Assert.isTrue(Protocol.isDispatchThread()); // The trace listener interface does not have a onChannelOpenend method, but // for consistency, log the channel opening similar to the others. if (CoreBundleActivator.getTraceHandler().isSlotEnabled(0, ITracing.ID_TRACE_CHANNEL_TRACE_LISTENER)) { CoreBundleActivator.getTraceHandler().trace("TraceListener.onChannelOpened ( " + channel + " )", //$NON-NLS-1$ //$NON-NLS-2$ ITracing.ID_TRACE_CHANNEL_TRACE_LISTENER, this); } // The trace listeners can be accessed only via AbstractChannel if (!(channel instanceof AbstractChannel)) return; // Get the preference key if or if not logging is enabled boolean loggingEnabled = Platform.getPreferencesService().getBoolean(CoreBundleActivator.getUniqueIdentifier(), IPreferenceKeys.PREF_LOGGING_ENABLED, false, null); // If false, we are done here and wont create any console or trace listener. if (!loggingEnabled) return; // As the channel has just opened, there should be no trace listener, but better be safe and check AbstractChannel.TraceListener traceListener = listeners.remove(channel); if (traceListener != null) ((AbstractChannel)channel).removeTraceListener(traceListener); // Create a new trace listener instance traceListener = new ChannelTraceListener(channel); // Attach trace listener to the channel ((AbstractChannel)channel).addTraceListener(traceListener); // Remember the associated trace listener listeners.put(channel, traceListener); // Log the channel opening String date = ChannelTraceListener.DATE_FORMAT.format(new Date(System.currentTimeMillis())); String message = NLS.bind(Messages.ChannelTraceListener_channelOpened_message, new Object[] { date, Integer.toHexString(channel.hashCode()) }); // Get the file writer FileWriter writer = LogManager.getInstance().getWriter(channel); if (writer != null) { try { writer.write(message); writer.write("\n"); //$NON-NLS-1$ writer.flush(); } catch (IOException e) { /* ignored on purpose */ } } } /** * Channel closed. Detach the channel trace listener if any. * * @param channel The channel. Must not be <code>null</code>. */ public void onChannelClosed(final IChannel channel) { Assert.isNotNull(channel); Assert.isTrue(Protocol.isDispatchThread()); // The trace listeners can be accessed only via AbstractChannel if (!(channel instanceof AbstractChannel)) return; // Remove the trace listener if any final AbstractChannel.TraceListener traceListener = listeners.remove(channel); if (traceListener != null) { Protocol.invokeLater(new Runnable() { @Override public void run() { ((AbstractChannel)channel).removeTraceListener(traceListener); } }); } } }