More on OSA's New Tools Platform, ConsoleOne
Articles and Tips: article
Senior Research Engineer
Developer Information
01 Mar 1998
- Introduction
- ConsoleOne Class Hierarchy
- A Snap-in for All Reasons
- Navigating Namespaces
- Namespace Discovery
Introduction
If you have read some of the earlier articles on OSA (Open Solutions Architecture) in this issue, you have learned that it is a brave new day at Novell. We are committed to making your applications easier to register, discover, install, configure, manage, and update across the network.
You've probably already heard that Novell was working on a new Java-based administration tool. You probably think that this new tool will replace the Wintel-based NetWare Administrator application. Well, as this article will explain, this assumption is both right and wrong.
The new Java-based administration tool to be released with NetWare 5 will be called ConsoleOne. Although, it will perform basic NDS administration in the NetWare 5 release, this version will not yet provide the same level of functionality as good old NetWare Administrator.
On the other hand, there are some notable benefits even with this early version of ConsoleOne. First, it will run on any platform which can run a Java virtual machine, including the NetWare server. Second, ConsoleOne can be extended to browse and interact with just about any namespace imaginable. You see, ConsoleOne is not just an NDS administration tool, it is really a namespace browser and tools receptacle. But, what do we mean by a namespace?
The term namespace as it would be used for ConsoleOne is any container which contains objects with names. Examples of a namespace could be a directory like NDS, a file system, or any database. So then, any entity on the network which contains things that are accessible by name could ultimately be browsed and managed by ConsoleOne (with a little work from you, of course).
Eventually, Novell may even deliver a version of ConsoleOne as an applet to allow administrators to manage their networks from any browser.
NetWare 5's version of ConsoleOne however, is a Java stand-alone application.
ConsoleOne Class Hierarchy
On the following pages, you will find a class hierarchy listing to give you a quick idea of the makeup of ConsoleOne.
class java.lang.Object
interface com.novell.application.console.snapin.AskPerInstanceSnapin
class java.awt.Component
class java.awt.Container
class com.sun.java.swing.JComponent
class com.sun.java.swing.AbstractButton
class com.sun.java.swing.JMenuItem
class
com.novell.application.console.snapin.DefaultMenuItem
class com.sun.java.swing.JComboBox
class
com.novell.application.console.util.objectentryselector.TreeCombo
class java.awt.Panel
class com.novell.application.console.snapin.SimplePageSnapin
class java.awt.Window
class java.awt.Dialog
class com.sun.java.swing.JDialog
class
com.novell.application.console.util.objectentryselector.ObjectEntrySelector
class com.novell.utility.nmsgbox.NMsgBox
interface com.novell.application.console.snapin.DisplayImageSnapin
interface com.novell.application.console.snapin.DisplayNameSnapin
class java.util.EventObject
class com.novell.application.console.snapin.ShellEvent
class com.novell.application.console.snapin.PageHostEvent
class com.novell.application.console.snapin.SnapinEvent
interface com.novell.application.console.snapin.ExtendChildrenSnapin
class com.novell.application.console.snapin.MainShell
interface com.novell.application.console.snapin.MenuSnapin
interface com.novell.application.console.snapin.NameMapSnapin
interface com.novell.application.console.snapin.NamespaceSnapin
class com.novell.application.console.snapin.ObjectEntry
interface com.novell.application.console.snapin.ObjectEntryEnumeration
class
com.novell.application.console.util.objectentryselector.ObjectEntryFilter
class com.novell.application.console.snapin.ObjectType
interface com.novell.application.console.snapin.PageHost
interface com.novell.application.console.snapin.PageSnapin
interface com.novell.application.console.snapin.PersistenceSnapin
interface com.novell.application.console.snapin.ProxySnapin
class java.util.ResourceBundle
class java.util.ListResourceBundle
class com.novell.utility.nmsgbox.Resources
interface com.novell.application.console.snapin.ServiceSnapin
interface com.novell.application.console.snapin.Shell
class com.novell.application.console.snapin.ShellAdapter
interface com.novell.application.console.snapin.ShellListener
class com.novell.application.console.snapin.SimpleContextMenuSnapin
class com.novell.application.console.snapin.SimpleStatusBarSnapin
class com.novell.application.console.snapin.SimpleToolBarMenuSnapin
interface com.novell.application.console.snapin.Snapin
class com.novell.application.console.snapin.SnapinCollectionInfo
class com.novell.application.console.snapin.SnapinItemInfo
interface com.novell.application.console.snapin.SnapinListener
interface com.novell.application.console.snapin.StatusBarSnapin
class java.lang.Throwable
class java.lang.Exception
class com.novell.application.console.snapin.SnapinException
class
com.novell.application.console.snapin.NoParentException
class
com.novell.application.console.snapin.NotAContainerException
class
com.novell.application.console.snapin.ObjectNotFoundException
class com.novell.application.console.snapin.SnapinVetoException
interface com.novell.application.console.snapin.ToolBarSnapin
interface com.novell.application.console.snapin.VetoableSnapinListener
interface com.novell.application.console.snapin.ViewSnapin
Notes:
The entries in the class hierarchy listing are in the form of fully qualified names. For example, in the entry, com.novell.application.console.snapin.NamespaceSnapin, the prefix com.novell.application.console.snapin specifies the location of the Java class package directory that contains the class NamespaceSnapin.
The dots (or ".") are name context delimiters. So, the DOS equivalent of the entry would be com\novell\application\console.snapin\NamespaceSnapin and this is what you would see if you looked inside of the JAR file.
The package statement that you write for each source file tells the build environment in which directory to put the classes compiled from the file. Usually, programmers put classes of like purpose together into the same directory or package. Often all of the packages relating to a given purpose are zipped up into the same JAR file which is then put into the ConsoleOne snap-ins directory so that ConsoleOne can accesss it (more on that later).
A Snap-in for All Reasons
ConsoleOne is designed to be extended to provide functionality for multiple namespaces. The namespace functionality can be whatever the namespace developer wants it to be, browsing and management being two obvious examples. Like the extensions for NetWare Administrator, ConsoleOne extensions are called snap-ins. ConsoleOne, however, provides a much higher-level of integration between its snap-ins and its shell than does NetWare Administrator.
The basic snap-in for a given namespace is called a NamespaceSnapin. So, for each namespace to be browsed or managed by ConsoleOne there will be an implementation of NamespaceSnapin to perform name context resolution within that domain. All communications to and from ConsoleOne snap-ins are done using predefined snap-in methods that the shell knows about. These methods are defined in Java interfaces. (Java interfaces are something like C++ abstract classes, in that you cannot instantiate them.)
The purpose of Java interfaces is to provide a contract between objects. In the case of a ConsoleOne snap-in, because the shell knows that your snap-in implements a ConsoleOne snap-in interface, it knows what methods to call in your snap-in and it knows that your snap-in will then do the right thing for its target namespace. Can you say polymorphism?
So then, every snap-in must implement the methods defined for it in one of ConsoleOne's snap-in interfaces (there are several different types to accomodate the different kinds of snap-ins, namespace for example). Below is an inheritance hierarchy for some of the snap-in interfaces available today, along with a one-line description of how they would be used.
java.lang.Object
Snapin
NamespaceSnapin - to control name context resolution in a namespace
ViewSnapin - to manage how a namespace or object is displayed in the
namespace view of the ConsoleOne window.
DisplayImageSnapin - to provide the image for an object in a given namespace.
PageSnapin - to provide object/attribute info to MPEC property book pages
ToolBarSnapin - to add tool controls to ConsoleOne tool bar
MenuSnapin - to add menus/menu items to ConsoleOne window.
StatusBarSnapin - to display status messages in ConsoleOne status bar.
ServiceSnapin - to make functionality available to other snapins.
Navigating Namespaces
The main ConsoleOne window is shown in Figure 1. There are two main panes in the window. The one on the left allows you to select the namespace of interest; the one on the right displays the contents of that namespace.
Figure 1: A ConsoleOne window with the NDS namespace "MyTree" displayed but unselected.

When ConsoleOne is launched, all of the namespaces are listed (including NDS trees) that this installation of ConsoleOne is configured to see. In the example shown in Figure 1, the only namespace available to the client is an NDS tree named myTree, which is currently unselected.
Figure 2: A ConsoleOne window with the NDS namespace "MyTree" selected.

In Figure 2, the user has selected the MyTree namespace. When a namespace selection is made, the contents of the namespace are displayed in the namespace view pane on the right. The objects displayed in the namespace view pane are called ObjectEntrys.
Note that when a namespace is selected, tool items specific to the namespace appear in the tools area and likewise menu extensions needed by the namespace are added. If the user were to then select a different kind of namespace, say a file system, the items from the previously selected namespace would be replaced by the items for the new one.
Namespace Discovery
ConsoleOne may be a namespace browser and tool platform, but it has no specific knowledge of any particular namespace. So how does ConsoleOne accomplish all of the namespace specific things that are needed for namespace navigation?
During its launch, ConsoleOne finds out what namespace snap-ins it is configured with and in true object-oriented fashion, it lets them handle their own affairs. When ConsoleOne is launched, it looks in its root directory for another directory called snap-ins. The snap-ins directory contains all of the snap-in executables which make ConsoleOne useful. Shown in Figure 3 is the snap-ins directory in a standard ConsoleOne install.
Figure 3: Each snap-in is packaged in a JAR file. The JAR file is placed in the .\snapins directory relative to where ConsoleOne is executed.

Inside of the snap-ins directory ConsoleOne finds all of its snap-in classes contained in Java JAR files. (JAR files are zip files containing Java classes, images, and other data along with a manifest file describing the JAR's contents.) If the JAR has a manifest, ConsoleOne will read it to obtain information on all of the snap-ins it contains. If the JAR does not contain a manifest, ConsoleOne will parse each JAR file to see if it is a snap-in.
ConsoleOne loads all of the snap-ins that it finds in the JARs and then calls each of their getRegistration() methods. As shown in Figure 4, the getRegistration() method is one of the methods specified in the basic Snap-in interface. As such, it is inherited by all of Snap-in's descendant interfaces thereby requiring all snap-ins to implement this method.
Each snap-in's getRegistration( ) method provides ConsoleOne with information about what kind of snap-in it is and what namespaces and/or object types in those namespaces that it is interested in. A code-level explanation of getRegistration( ) can be found in "Snapping Your NDS App in to ConsoleOne" later in this issue. To efficiently manage memory, ConsoleOne unloads all snap-ins after the registration process is complete.
Snap-in to Shell to Snap-in Communication. After registration, snap-ins are loaded and initialized on an as-needed basis. At this point ConsoleOne knows what namespaces it is configured with. It also knows which snap-ins are registered with each namespace and object type so it can load them appropriately. However, when a snap-in is loaded it has no knowledge of ConsoleOne. To give the snap-in access to ConsoleOne functionality and to give it a chance to initialize before operation, ConoleOne immediately calls another required method, initSnapin(Shell shell) after loading the snap-in.
Access to ConsoleOne functionality is provided through the object reference to ConsoleOne's Shell object given to the snap-in with initSnapin( ). The shell object provides a wealth of accessor routines that a snap-in can then use to obtain references to other ConsoleOne objects, including the NamespaceSnapin currently selected in the browser.
The following transactions are typical of what might occur in order for ConsoleOne to obtain an appropriate view or GUI for a newly selected namespace. As you read along, find the objects and methods in the object diagram shown in Figure 4. If you can do this, you will have the necessary basic understanding of the interractions between the shell and its snap-ins.
ConsoleOne loads the view snap-in registered for the selected namespace.
shell.view.initSnapin(shell ) ConsoleOne calls view.initSnapin( ) in the newly loaded view snap-in passing it a reference to its shell object. The view snap-in saves the shell object reference in its own variable.
shell.view.getView( ) The shell calls the view snap-in's getView( ) method to obtain the GUI for the newly selected namespace.
shell.view.getView( ).shell.getTreeSelection( ) The view snap-in must get a list of ObjectEntrys in the current context in order to figure out what images to draw and where. So, the view snap-in uses its shell reference to call the shell's getTreeSelection( ) method to obtain the currently selected parent ObjectEntry (the selected ObjectEntry establishes current context). The shell returns the ObjectEntry representing the namespace since it was just selected.
shell.view.getView( ).shell.getChildren( ) The view then passes this ObjectEntry to the shell's getChildren( ) method as the parent parameter.
shell.view.getView( ).shell.getChildren( ).parent. getType( ) The shell's getChildren( ) method uses the parent ObjectEntry's getType( ) method to get an ObjectType object containing the parent's type information.
shell.view.getView( ).shell.getChildren( ).parent. type.getNameSpace( ) The shell's getChildren( ) method then calls the getNameSpace( ) method in the parent's type object to obtain an object reference to its namespace.
shell.view.getView( ).shell.getChildren ( .parentsNamespace.getChildren( ) The shell's getChildren( ) method finally calls the getChildren( ) method in the namespace object. The shell forwards the returned ObjectEntryEnumeration object (a collection of the ObjectEntrys to be displayed) back to the view.
shell.view.getView( ).shell.getDisplayImage( ) Still in its getView( ) method, for each entry in the Enumeration, the view calls the shells getDisplayImage( ) method to obtain its Image and the shell's getDisplayName( ) method to obtain its name.
shell.view.getView( ).shell.getDisplayImage( ).entry.getType( ) The shell's getDisplayImage( ) method gets an ObjectType object for each ObjectEntry.
shell.view.getView( ).shell.getDisplayImage ( ).getRegisteredDisplayImageSnapin( ) The shell's getDisplayImage( ) method then looks up the DisplayImageSnapin registered for the object type.
shell.view.getView( ).shell.getDisplayImage ( ).imgSnapin.getDisplayImage( ) The shell's getDisplayImage( ) method then calls the DisplayImageSnapin's getDisplayImage( ) method, returning the Image to the view.
shell.view.getView( ).shell.getDisplayName( ) In a similar fashion, each call to the shell's getDisplayName( ) method instantiates a registered DisplayNameSnapin object which is used to obtain a name for the view.
shell.view.getView( ) Finally, the view adds the images and names to a Java GUI Panel, arranging them in a way that it wants them displayed and returns the Panel to the ConsoleOne shell as the View Component.
shell.guiView.paint() ConsoleOne renders the Panel into the namespace view pane.
Figure 4: Simplified ConsoleOne object model diagram for discussion purposes only.

Disclaimer
The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.