package org.marketcetera.photon.internal.module.ui; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleFactory; import org.eclipse.ui.console.IConsoleListener; import org.eclipse.ui.console.IConsoleManager; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; import org.marketcetera.event.LogEvent; import org.marketcetera.event.LogEventLevel; import org.marketcetera.module.DataFlowID; import org.marketcetera.photon.module.IDataFlowLabelProvider; import org.marketcetera.photon.module.ISinkDataHandler; import org.marketcetera.photon.module.ISinkDataManager; import org.marketcetera.photon.module.ModuleSupport; import org.marketcetera.photon.module.SinkDataHandler; import org.marketcetera.util.misc.ClassVersion; /* $License$ */ /** * Manages the Sink Console. * * This class may be subclassed to override * <ul> * <li>{@link #format(Object, Object)} - to customize formatting of data</li> * </ul> * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: SinkConsoleController.java 16154 2012-07-14 16:34:05Z colin $ * @since 1.0.0 */ @ClassVersion("$Id: SinkConsoleController.java 16154 2012-07-14 16:34:05Z colin $")//$NON-NLS-1$ public class SinkConsoleController implements IConsoleFactory, IConsoleListener { /** * Eclipse console manager */ private final IConsoleManager mConsoleManager; /** * Sink data manager */ private final ISinkDataManager mSinkDataManager; /** * The sink console */ private MessageConsole mConsole; /** * The current handler */ private InternalHandler mHandler; /** * Constructor. */ public SinkConsoleController() { mConsoleManager = ConsolePlugin.getDefault().getConsoleManager(); mConsoleManager.addConsoleListener(this); mSinkDataManager = ModuleSupport.getSinkDataManager(); } /** * This implementation of {@link IConsoleFactory#openConsole()} shows the Sink Console. * * This method is called by the Eclipse framework when a user selects the action associated to * this {@link IConsoleFactory}. */ @Override public final void openConsole() { if (mConsole == null) { mConsole = new MessageConsole(Messages.SINK_CONSOLE__NAME.getText(), null); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { mConsole }); mHandler = new InternalHandler(mConsole.newMessageStream()); } mConsoleManager.showConsoleView(mConsole); } /** * Formats the notification object into a String. * * Subclasses may override to provide different formatting. * * @param inFlowID * the data flow ID * @param inData * the data flow data object * @return a string representation of <code>inData</code> to write to the Sink Console, must not * be null */ protected String format(final DataFlowID inFlowID, final Object inData) { return Messages.SINK_CONSOLE_CONTROLLER_MESSAGE_FORMAT.getText( getLabel(inFlowID), inData.toString()); } private String getLabel(DataFlowID dataFlowId) { IDataFlowLabelProvider labelProvider = ModuleSupport.getDataFlowLabelProvider(); if (labelProvider != null) { String label = labelProvider.getLabel(dataFlowId); if (label != null) { return label; } } return dataFlowId.getValue(); } /** * This implementation of {@link IConsoleListener#consolesAdded(IConsole[])} does nothing. */ @Override public final void consolesAdded(final IConsole[] consoles) { // Do nothing } /** * This implementation of {@link IConsoleListener#consolesRemoved(IConsole[])} cleans up the * Sink Console if it was removed. */ @Override public final void consolesRemoved(final IConsole[] consoles) { for (int i = 0; i < consoles.length; i++) { if (consoles[i] == mConsole) { mHandler.dispose(); mConsole = null; return; } } } /** * Internal helper class to register default handling of sink data and manage synchronization. * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: SinkConsoleController.java 16154 2012-07-14 16:34:05Z colin $ * @since 1.0.0 */ @ClassVersion("$Id: SinkConsoleController.java 16154 2012-07-14 16:34:05Z colin $")//$NON-NLS-1$ private final class InternalHandler extends SinkDataHandler { /** * The console output stream */ private MessageConsoleStream mStream; /** * Constructor. * * @param stream * stream to publish data */ private InternalHandler(MessageConsoleStream stream) { mStream = stream; mSinkDataManager.registerDefault(this); } /** * This implementation of {@link ISinkDataHandler#receivedData(DataFlowID, Object)} writes * the object to the console stream. The object is formatted to a String using the parent * {@link SinkConsoleController#format(Object)}. */ @Override public void receivedData(DataFlowID inFlowID, Object inData) { // only log log events if the category is higher than USER_MSG_CATEGORY if (!(inData instanceof LogEvent) || LogEventLevel.shouldLog((LogEvent)inData, org.marketcetera.core.Messages.USER_MSG_CATEGORY)) { mStream.println(format(inFlowID, inData)); } } /** * Stops handler from writing to console stream. After this method has been called, this * object should no longer be used. */ private synchronized void dispose() { mSinkDataManager.unregisterDefault(this); mStream = null; } } }