package org.marketcetera.photon.notification;
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.core.notifications.INotification;
import org.marketcetera.core.notifications.INotificationManager;
import org.marketcetera.core.publisher.ISubscriber;
import org.marketcetera.util.misc.ClassVersion;
/* $License$ */
/**
* Manages the Notification Console.
*
* This class may be subclassed to override
* <ul>
* <li>{@link #isInteresting(Object)} - to filter notifications</li>
* <li>{@link #format(Object)} - to customize formatting of notifications</li>
* </ul>
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: NotificationConsoleController.java 16154 2012-07-14 16:34:05Z colin $
* @since 0.8.0
*/
@ClassVersion("$Id: NotificationConsoleController.java 16154 2012-07-14 16:34:05Z colin $")//$NON-NLS-1$
public class NotificationConsoleController implements IConsoleFactory,
IConsoleListener {
/**
* Eclipse console manager
*/
private final IConsoleManager mConsoleManager;
/**
* Core notification manager
*/
private final INotificationManager mNotificationManager;
/**
* The notification console
*/
private MessageConsole mConsole;
/**
* The current notification subscriber
*/
private InternalSubscriber mSubscriber;
/**
* Constructor.
*/
public NotificationConsoleController() {
mConsoleManager = ConsolePlugin.getDefault().getConsoleManager();
mConsoleManager.addConsoleListener(this);
mNotificationManager = NotificationPlugin.getDefault()
.getNotificationManager();
}
/**
* This implementation of {@link IConsoleFactory#openConsole()} shows the
* Notification 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) {
Messages.NOTIFICATION_CONSOLE_INIT.info(this);
mConsole = new MessageConsole(Messages.NOTIFICATION_CONSOLE_NAME
.getText(), null);
ConsolePlugin.getDefault().getConsoleManager().addConsoles(
new IConsole[] { mConsole });
mSubscriber = new InternalSubscriber(mConsole.newMessageStream());
}
mConsoleManager.showConsoleView(mConsole);
}
/**
* Determines if the data should be published to the Notification Console.
* This default implementation returns <code>true</code> for all
* {@link INotification} <code>inData</code>.
*
* Subclasses may override to provide custom filtering.
*/
protected boolean isInteresting(final Object inData) {
return inData instanceof INotification;
}
/**
* Formats the notification object into a String. Default implementation
* returns {@link Object#toString()}.
*
* Subclasses may override to provide different formatting.
*
* Note this will only be called for <code>inData</code> that are considered
* "interesting". See {@link #isInteresting(Object)}.
*
* @param inData
* the object to format
* @return a string representation of <code>inData</code> to write to the
* Notification Console, must not be null
*/
protected String format(final Object inData) {
return inData.toString();
}
/**
* 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
* Notification 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) {
mSubscriber.dispose();
mConsole = null;
return;
}
}
}
/**
* Internal helper class to subscribe to notifications and handle
* synchronization.
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: NotificationConsoleController.java 16154 2012-07-14 16:34:05Z colin $
* @since 0.8.0
*/
@ClassVersion("$Id: NotificationConsoleController.java 16154 2012-07-14 16:34:05Z colin $")//$NON-NLS-1$
private final class InternalSubscriber implements ISubscriber {
/**
* The stream to publish notifications
*/
private MessageConsoleStream mStream;
/**
* Constructor.
*
* @param stream
* stream to publish notifications
*/
private InternalSubscriber(MessageConsoleStream stream) {
mStream = stream;
mNotificationManager.subscribe(this);
}
/**
* This implementation of {@link ISubscriber#isInteresting(Object)}
* returns true if the Notification Console is available and the parent
* {@link NotificationConsoleController#isInteresting(Object)} returns
* true.
*/
@Override
public synchronized boolean isInteresting(Object inData) {
return mStream != null
&& NotificationConsoleController.this.isInteresting(inData);
}
/**
* This implementation of {@link ISubscriber#publishTo(Object)} writes
* the object to the Notification Console if available. The object is
* formatted to a String using the parent
* {@link NotificationConsoleController#format(Object)}.
*/
@Override
public synchronized void publishTo(Object inData) {
if (mStream != null)
mStream.println(format(inData));
}
/**
* Stops subscriber from writing to notification stream. After this
* method has been called, this object should no longer be used.
*/
private synchronized void dispose() {
mNotificationManager.unsubscribe(this);
mStream = null;
}
}
}