Novell is now a part of Micro Focus

More on OSA's New Tools Platform, ConsoleOne

Articles and Tips: article

LAWRENCE V. FISHER
Senior Research Engineer
Developer Information

01 Mar 1998


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:

  1. 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.

  2. 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.

  3. 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.

  1. ConsoleOne loads the view snap-in registered for the selected namespace.

  2. 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.

  3. shell.view.getView( ) The shell calls the view snap-in's getView( ) method to obtain the GUI for the newly selected namespace.

  4. 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.

  5. shell.view.getView( ).shell.getChildren( ) The view then passes this ObjectEntry to the shell's getChildren( ) method as the parent parameter.

  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. shell.view.getView( ).shell.getDisplayImage( ).entry.getType( ) The shell's getDisplayImage( ) method gets an ObjectType object for each ObjectEntry.

  11. shell.view.getView( ).shell.getDisplayImage ( ).getRegisteredDisplayImageSnapin( ) The shell's getDisplayImage( ) method then looks up the DisplayImageSnapin registered for the object type.

  12. 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.

  13. 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.

  14. 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.

  15. 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.

© Copyright Micro Focus or one of its affiliates