/* Font Definitions */ @font-face {font-family:"Times New Roman"; panose-1:0 2 2 6 3 5 4 5 2 3; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:50331648 0 0 0 1 0;} @font-face {font-family:Arial; panose-1:0 2 11 6 4 2 2 2 2 2; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:50331648 0 0 0 1 0;} @font-face {font-family:"Courier New"; panose-1:0 2 7 3 9 2 2 5 2 4; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:50331648 0 0 0 1 0;} @font-face {font-family:Verdana; panose-1:0 2 11 6 4 3 5 4 4 2; mso-font-charset:0; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:50331648 0 0 0 1 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin-right:0in; mso-margin-top-alt:auto; mso-margin-bottom-alt:auto; margin-left:0in; mso-pagination:widow-orphan; font-size:10.0pt; font-family:Times;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} p {font-size:10.0pt; font-family:Times;} code {} pre {margin:0in; margin-bottom:.0001pt; font-size:10.0pt; font-family:Times;} table.MsoNormalTable {mso-style-parent:""; font-size:10.0pt; font-family:"Times New Roman";} p.indextop, li.indextop, div.indextop {mso-style-name:indextop; font-size:24.0pt; font-family:Times;} p.indexsub, li.indexsub, div.indexsub {mso-style-name:indexsub; font-size:7.5pt; font-family:Times;} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.25in 1.0in 1.25in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;} div.Section1 {page:Section1;} -->

  © Copyright International Business Machines Corporation, 2004. All rights reserved

 Eclipse Corner Article


Jabbering Consoles

Summary
Traditionally, consoles are used to display output and provide input to programs. The console plug-in in the Eclipse SDK provides a flexible framework for building text based consoles complete with pattern matching and hyperlink support, and also clients to provide arbitrary implementations of consoles with custom presentations. This article showcases the console framework in Eclipse with an example implementation of a console that supports instant messaging.

By Darin Wright, IBM Rational Software Group
Kevin Barnes, IBM Rational Software Group

November 5, 2004


Introduction

The org.eclipse.ui.console plug-in provides a framework for building and managing consoles. A console view displays all registered consoles. Each console is displayed by a page within the console view, and a console may be visible in any number of console views at any given time. A console manager maintains the currently registered set of consoles, and provides notification when consoles are added and removed. All consoles registered with the manager are displayed in the console view.

An extensible implementation of text based consoles is provided by the console plug-in. A text console maintains a partitionable document supporting regular expression matching and hyperlinks. The most general text console is used for displaying and editing a document. For example, the Java Stack Trace Console contributed by the Java debugger is a text console that supports pasting and navigating stack traces. The more specialized I/O console is used to display read-only output streams and provides an input stream that accepts input from the keyboard. For example, when an application is launched from Eclipse, an I/O console is used to display its standard output and error streams and provide input to its standard input stream.

[insert image: the console view]

Basic API

The first thing that users think of when the console is mention is the Console View. This view is a PageBookView that contains a page for every console registered with the console manager. The Console View is an implementation of IConsoleView and clients may interact with the view to manage the features provided by the view such as displaying a specific console, pinning a console on top of other pages, and turn scroll lock on or off. Consoles are never added directly to a Console View, instead a Console View contains all consoles that have been added to the console manager.

The console manager’s API is defined by IConsoleManager, a singleton manager class available from the ConsolePlugin class via ConsolePlugin.getDefault().getConsoleManager(). All console’s added to a console manager will be displayed in all Console Views.

Every console implements IConsole, providing a name, and an optional image and type. The console plug-in provides an abstract base class that all console implementations are intended to subclass - AbstractConsole. The base class provides an implementation of function common to consoles: getters, setters, and change notification for name, image, and type attributes; infrastructure for adding and removing property change listeners and firing property change notification; and lifecycle methods for initialization and cleanup (init() and dispose()) that can be specialized in subclasses. Two subclasses of AbstractConsole are also provided by the console plugin. TextConsole does hyperlinking and regular expression pattern matching, and IOConsole which additionally provides a document partitioner and streams for interacting with the console.

The streams provided by IOConsole are regular java.io streams, but also allow you to set some stream specific attributes such as color and font style. The IOConsoleOutputStream also allows clients to specify whether the console should be activated when the stream is written to.

Page participants (IConsolePageParticipant) can be selectively contributed to text consoles via the consolePageParticipants extension point. A page participant can add actions to the console tool bar and context menu, provide adapters for the page, and implement custom function for the page. For example, the Java Stack Trace Console previously mentioned, contributes a page participant that adds Format and Close actions to the console tool bar.

Pattern matchers can also be contributed to text consoles selectively via the consolePatternMatchListeners extension point, or they can be programmatically added (TextConsole.addPatternMatchListener(IPatternMatchListener)). The most common use of pattern matching is to add hyperlinks (IHyperlink) to a text console.

Instant messaging

<Overview of the parts of our example: a console to send/receive messages and file transfer, a buddy list. Built using Jabber/Smack.>
Instant messaging has become an integral part of every day communication for many of us. Many messaging protocols and applications exist, but all share the same basic functionality - creation of a buddy list that informs us of our contacts availability, and ability to communicate with our buddies in real-time when they are available. The purpose of this article is to demonstrate how a simple instant messaging plug-in can be written quickly for Eclipse using Eclipse consoles and the Jabber protocols.

Jabber is an open set of protocols and technologies that allow for the exchange of messages, presence, and other structured information in close to real time. The Internet Engineering Task Force (IETF) has formalized the core set of jabber's protocols as an approved instant messaging and presence technology called Extensible Messaging and Presence Protocol (XMPP). Jive Software has developed an open source XMPP client library called Smack that we will be using to build our application.

When complete, our plug-in will consist of a new Buddy List view and will reuse existing consoles to send and receive messages.

The Supporting cast

<>Before jumping into the console itself it's necessary to spend some time discussing a few other classes that allow us to have a functioning chat client.

As with any chat application it's necessary to have a connection to a server before any messages can be sent or received. In this plug-in it is the ChatManager that is responsible for managing that connection. The ChatManager is an f
The central character is of course the connection to the server. Overview of the chat manager, chat session, and buddy view
Chat Manager
- the brains of the operation.
- Manages the connection (does the login, listens for incoming messages, and creates chat sessions)

Chat Session
- creates and manages a chat console (displays messages as they are received from other chat participants, reads from the console's input stream and sends messages to the other participant)

RosterView
- I should probably just call this Buddy View for clarity.
- Tree Viewer. Displays Buddy groups, buddies and their current precence.
- Does it allow you to add buddies/groups? It should.

Login Dialog
- allows login and register. Explain register... most users probably won't have a jabber screen name.  

The chat console

Since the purpose of this article is really to demonstrate how the Eclipse Console Framework makes some task very simple, our chat application is going to be console based. The framework does a few things to make our lives easier. It provides a common view that will display all of our consoles for us, it provides generic and reusable base implemenations of consoles that cna be used as is, and it provides the necessary API to allow for the creation of custom consoles. Anyone wishing to implement a Text based console should consider using or extending the base implementions - Text Console and IOConsole (for stream based consoles) - provided by the framework.

For each chat session we'll be using an IOConsole as is. The functionality provided by the base console is enough to do what we require for demonstration purposed. Creating a console is simple and done by the constructor of ChatSession:

<code> fConsole = new IOConsole("Chat: " + fChat.getParticipant(), "Chat", null); </code>

Adding the console to the view is done later in the same constructor. It's as simple as adding the console to the IConsoleManager provided by the console plugin:
<code>
        IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
        consoleManager.addConsoles(new IConsole[] { fConsole });
</code>

Every IOConsole is stream based, we can write to the console by creating an IOConsoleOutputStream
<code>fConsole.newOutputStream();<code>
and using its write() methods.

<>IOConsole allows you to create as many IOConsoleOutputStreams as you need.It also allows for each stream to be presented uniquely in the console with methods such as setFontStyle(int newFontStyle), and setColor(Color color). It also allow you to decide whether or not the ConsoleView should be "activated" when the stream is used. Explain activation quickly now. For our demo we only need one output stream, but we will change it's color to differentiated messages we send from those that we receive. Remember that accessing you need to use the UI thread to access system colors. The code looks like this:
<code>
final Display display = ChatPlugin.getStandardDisplay();
        display.asyncExec(new Runnable() {
            public void run() {
                fIn.setColor(display.getSystemColor(SWT.COLOR_DARK_BLUE));
                out.setColor(display.getSystemColor(SWT.COLOR_DARK_RED));
                out.setActivateOnWrite(true);
            }
        });
        fOut = new PrintStream(out); // for convenience
</code>

This output stream will be used to write messages that we receive to our console, but we also want to be able to send messages. For this we'll need to use the IOConsoleInputStream provided by the IOConsole. IOConsole only provides one input stream via the getInputStream() method. The IOConsoleInputStream is very similar to the related output stream. Anything that the user types into the console will be accessible via the streams read() methods once the user hits "enter". We'll start a thread to read from the input stream, and send each message as it's entered. Our thread will do the following.
<code>
            int read = 0;
            byte[] bytes = new byte[1024];
            try {
                while (!fKilled && read >= 0) {
                    read = fIn.read(bytes);
                    if (read > 0)
                        fChat.sendMessage(new String(bytes, 0, read));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (XMPPException e) {
                e.printStackTrace();
            }
            close();
</code>

With very little code we have been able to create and display a new console that is able to display messages from other users and respond to them.

Pattern matching and hyperlinks

Use pattern matching to find URLs, add hyperlinks for URLs, also add hyperlinks to use name for "add user".
Explain the console pattern matching with URL example.
Walk through add user enough to show that pattern matchers can be added programmatically.

The page participant

Adds action for file transfer, and pattern matching for painting a smily face
- Actually does none of the above. Only adds remove console to the tool bar.
- Avoid discussing command/context stuff here. Too messy. If anyone asks give them Doug's email address and home phone number.

The console factory

a factory to open a chat session
Pretty simple stuff. screen shots and code. not too much explanation needed. Maybe talk about other console factories??

Other stuff?

tip: to warn of content change in a console

Summary and further information

Stress resusable, extensible, simple... themes Built to last and Ease of Use. Show that we make people's lives easy.
The Eclipse platform provides a very powerful framework that enables.
jabber.org link for XMPP information
Jive Software (Smack) http://www.jivesoftware.org/smack/

Acknowledgements

Thanks to people for their careful reviews and critiques that have improved this paper.

Source code

To examine the entire source code, or to run the example, download the zip file and unzip it into your Eclipse directory. The plug-in comes with complete source code. This article describes, and the included code requires, features that are available in Eclipse 3.1 M3 or a later version.

Trademarks

IBM and Rational are registered trademarks of International Business Machines Corporation in the United States, other countries, or both.

Linux is a trademark of Linus Torvalds in the United States, other countries, or both.

Microsoft and Windows are trademarks of Microsoft Corporation in the United States, other countries, or both.

Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.

Other company, product, and service names may be trademarks or service marks of others.