An integrated development environment (IDE), while not necessary, can provide features (such as debugging) that simplify the process of creating a snap-in. Setting up an IDE involves creating a project that compiles your snap-in to the appropriate directory and executes ConsoleOne. Each IDE requires a unique procedure to set it up for snap-in development, but there are a few general steps that you can adapt to your IDE.
To set up an IDE to develop a snap-in:
Create a new project.
Create a directory in SDK_HOME\snapins, where SDK_HOME represents the location where you installed the version of ConsoleOne included in the SDK. The directory name should represent your company name or some other functional grouping. For example, if you installed the SDK to C:\Novell\ConsoleOne, you might create the directory, C:\Novell\ConsoleOne\snapins\mycompanyname.
Set the output directory for compiled classes to the directory you created in the previous step.
Add all needed JAR files to the classpath, including
Set the main class to com.novell.application.console.shell.Console.
Add all of your snap-in source files to the project.
Save the project.
To run or debug your snap-in, issue the appropriate command in your IDE. ConsoleOne will start up and load your snap-in, which you can then test.
Your selection of snap-in types will depend upon the functionality you want to provide in ConsoleOne. ConsoleOne provides a default console, which extends the shell by providing a minimal set of content to the object browser, main menu and toolbar. You can extend the ConsoleOne shell by writing snap-ins to provide application-level features and functionality or to enhance other snap-ins.
In order for ConsoleOne to recognize your snap-in, you must implement the Registration interface. The implementation of the Registration interface should be in a separate class. The class which implements the Registration interface must be placed in the snapin directory. The Registration interface defines a single method, getRegistration().
public RegistrationItem[] getRegistration()
At start-up, ConsoleOne calls the getRegistration() method of each snap-in. The getRegistration() method returns a RegistrationItem array, which contains information identifying the snap-in type, where to find it, and when ConsoleOne will load the snap-in.
The different types of snap-ins are loaded at different times. Namespace and service snap-ins are loaded when ConsoleOne starts, and are kept loaded until shutdown. Toolbar, status bar, and menu snap-ins are evaluated when the tree selection changes to an object in a different namespace. Views are evaluated whenever the tree selection changes. Property Page snap-ins are evaluated when the property book is displayed.
The RegistrationItem class defines two constructors:
public RegistrationItem(Scope theScope, String className)
public RegistrationItem(Scope theScope, String className, Object instanceData)
The first constructor creates a RegistrationItem based on two parameters, the Scope of participation and the snap-in class name. The Scope parameter identifies the conditions under which the snap-in will appear in ConsoleOne. The className parameter is a string containing the full name of the snap-in class that is to be registered to ConsoleOne.
The second constructor has an additional parameter, instanceData. The instanceData parameter can contain any Java object that will be passed to the snap-in through the setInstanceData(Object instanceData) method, which is derived from the Template interface. Any time you use the instanceData parameter in RegistrationItem, you must implement the Template interface in the snap-in you create in order to retrieve the instanceData object. For further information on implementing the Template interface see Writing Multiple Snap-ins in a Single Class.
Registration of a snap-ins can be done in two different ways:
The preferred way to register a snap-in is to implement the Registration interface in a separate registration class, separate from your snap-in class, to contain the registration information for your snap-in. This registration class can contain the registration information for multiple snap-ins, eliminating the need to implement the getRegistration() method within each individual snap-in class that you create. This registration technique is more efficient at startup time than implementing the Registration interface in each snap-in class. The following code example creates a registration class that will register four different snap-ins (ExamplePage, ExampleStatusBar, ExampleMenu and ExampleToolBar) all within the Example namespace.
public class MyRegistrar implements Registration
{
public RegistrationItem[] getRegistration()
{
RegistrationItem[] ri = new RegistrationItem[4];
ri[0] = new RegistrationItem(new NamespaceScope(Shell.SNAPIN_PAGE, "Example"), "com.example.snapins.ExamplePage");
ri[1] = new RegistrationItem(new NamespaceScope(Shell.SNAPIN_STATUSBARITEM, "Example"), "com.example.snapins.ExampleStatusBar");
ri[2] = new RegistrationItem(new NamespaceScope(Shell.SNAPIN_MENU, "Example"), "com.example.snapins.ExampleMenu");
ri[3] = new RegistrationItem(new NamespaceScope(Shell.SNAPIN_TOOLBARITEM, "Example"), "com.example.snapins.ExampleToolBar");
return ri;
}
}
The ConsoleOne shell registers each snap-in in a collection by loading each class file in the collection. The shell checks to see if each class file implements the Registration interface, and if so, calls the getRegistration() method. To speed up registration by preventing every class in a large collection from being checked, you can include a manifest file in the collection that identifies which classes are registration classes. This might be done particularly when many classes in a large collection are supporting classes.
Snap-in classes are packaged into JAR collection files and placed in the Snapins directory relative to where ConsoleOne is installed. At startup, the ConsoleOne shell then registers all of the snap-ins in such JAR collections by loading each class file in the collection which implements the Registration interface. In a process called introspection, the shell checks each class found in the JAR file to see if it implements the Registration interface, and if so, calls its getRegistration() method.
To prevent every class in a large snap-in collection from being checked, you can include a manifest file in the JAR file that identifies which classes implement the Registration interface. This should be done when many of the classes in a large collection are merely "supporting classes" since ConsoleOne can quickly load the appropriate registration classes without introspecting all the classes in the JAR.
The JAR collection file contains identification information which is provided in the header section of the manifest file. The information that the shell is looking for includes
Each class listed in the manifest file that includes the tag "Snapin-Registrar:True" will be registered by ConsoleOne. All other classes will be ignored.
For example, suppose company "Xyz Corp. developed two snap-ins (ExampleFileNamespace and ExampleFileNamespaceDisplay) within a directory structure under "com/xyz/snapin". A manifest file for these snap-ins might look like this:
Manifest-Version: 1.0 Snapin-Collection-Name: Example File Manager Snapin-Collection-Description: File System Manager Snapin Snapin-Collection-Copyright: (c) Xyz Corp., 1997. All rights reserved. Specification-Version: 1.2 Implementation-Version: 1.5 Snapin-Collection-AutoRegister: False Name: com.xyz.snapin.ExampleFileNamespace.class Snapin-Registrar: True Name: com.xyz.snapin.ExampleFileNamespaceDisplay.class Snapin-Registrar: True
The manifest file and the accompanying class files should be added to a JAR file, which should be placed in the ConsoleOne snapins directory. The snap-ins will be registered during the ConsoleOne startup as described above.
Several methods must be implemented in each snap-in class that you create. Each of the snap-in interfaces (namespace, view, property page, menu, toolbar, status bar, etc.) is a subinterface of the Snapin interface, which defines the following four methods:
NOTE:For some required methods, as well as other methods defined in the ConsoleOne SDK, null values may be passed as parameters. In those cases where a null value can be passed, a note is included in the method and parameter documentation indicating that a null value is valid. For all other methods not specifically noted, null values are not valid parameters.
The getSnapinName() method allows the shell to provide a descriptive, localized name (translated string object) for your snap-in. You should implement this method to return a name for the selected snap-in. The getSnapinName() method will be called before the initSnapin() method. The getSnapinName() method can be implemented as follows:
public String getSnapinName()
{
return "Snap-in Name";
}
The getSnapinDescription() method allows the shell to provide the localized description (translated string object) of your snap-in. You should implement this method to return a description for the selected snap-in. The description should be kept brief and concise. The getSnapinDescription() method will be called before the initSnapin() method. The getSnapinDescription() method is implemented as follows:
public String getSnapinDescription()
{
return "Snap-in Description";
}
The initSnapin() method is called by the shell to allow the snap-in to be initialized. The getSnapinName() and getSnapinDescription() methods will be called before initSnapin(). The initSnapin() method allows the snap-in to perform any necessary initialization and to pass references to the InitSnapinInfo class. Examples of this initialization might be to add itself as an event listener or read data from a data store. The initSnapin() method is implemented as follows:
public boolean initSnapin(InitSnapinInfo info)
{
shell = info.getShell();
type = info.getSnapinType();
context = info.getSnapinContext();
.
. /*Initialize snap-in; return true if successful,
. otherwise return false.*/
.
return true;
}
The snap-in should return true if it is able to successfully complete initialization, or if initialization fails, false is returned and the specific instance of the snap-in will be disabled. The initSnapin() method has a single parameter, info, which contains data the snap-in can use, such as a reference to the shell, a reference to the snap-in type, and can contain a reference to snap-in context data. This information is defined in two associated classes.
The InitSnapinInfo class defines two constructors and three methods that can be implemented.
These constructors build a new InitSnapinInfo object with references to the shell, the snap-in type and, optionally in the second constructor, the snap-in context. The reference to the shell (shell parameter) can be used by snap-ins to interact with the shell. The reference to the snap-in type (snapinType parameter) is used when a snap-in class implements more than one type of snap-in. The snap-in context (context parameter) provides a reference to the context class defining the context in which the participating snap-in will exist.
The three methods defined in the InitSnapinInfo class are:
The getShell() method returns a reference to the ConsoleOne shell. This reference can be used by snap-ins to interact with the shell.
shell = info.getShell()
The getSnapinType() method returns a reference to the snap-in type of the participating snap-in. This reference can be used when a class implements more than one snap-in type.
type = info.getSnapinType()
The getSnapinContext() method returns a reference to the snap-in context of the participating snap-in. The snap-in context is dependent upon the snap-in type. For a particular snap-in type you need to cast the return value to the correct SnapinContext. For some snap-in types there is no defined snap-in context, therefore a null can be returned.
context = info.getSnapinContext()
The SnapinContext class is the base class from which all snap-in context classes are derived. Classes derived from the SnapinContext base class contain information on the current state of the Object Browser window, such as which entries are selected, and so forth. This information is usually available during snap-in initialization and can be extracted into private data fields for use by the snap-in methods. Classes derived from the SnapinContext base class are provided to wrap the objects needed by various snap-ins so they do not have to go to the shell to get them.
For example, pop-up menu snap-ins need to know what ObjectEntry array was selected when they were brought up. These snap-ins can get this ObjectEntry array from the PopupMenuSnapinContext, which is passed to them inside the InitSnapinInfo class of their initSnapin() method.
Because each snap-in has a different life cycle and each snap-in needs different data from the shell, the snap-in contexts are passed in at different times. Not all snap-ins can get their snap-in context in initSnapin() because it might not be known at the time. In these cases the reference to snap-in context will be null. That is, the SnapinContext parameter in the InitSnapinInfo constructor is set to null.
All relevant context information is packaged in the info parameter supplied to the initSnapin() method. The context is extracted from the info object by calling info.getContext() and casting it to the appropriate SnapinContext. If a NULL is returned, no context is defined for that particular snap-in class.
The View snap-in obtains its context information about the state of the Object Brower window directly through the ViewSnapinContext object that is passed to its getView() method. Calling the ViewSnapinContext getObjectEntry() method returns the currently selected ObjectEntry in the Object Browser window for which a view is needed.
The current Object Browser context is also stored in the InitSnapinInfo object supplied to the initSnapin() method during ViewSnapin initialization. A callto the getSnapinContext() method during initialization will return a valid ViewSnapinContext object for that point in time. However, the context can change between initialization and the call to the getView() method. Therefore, the context should be obtained from the ViewSnapinContext parameter supplied in the getView() method and not from the context provided in the InitSnapinInfo parameter supplied to the initSnapin() method during the ViewSnapin initialization.
The following table summarizes the data contained in the contexts for the various snap-in classes. It shows when a snap-in context is valid for the different snap-in types, what context class is available for use, what each context class contains, and in what method it is passed.
Table 2-1 Valid Snap-in Context Classes for Snap-in Types
The shutdownSnapin() method is called by the shell when the snap-in is being shut down. This method is called by the shell for each snap-in when it is no longer required. This allows the snap-in to perform any necessary cleanup, such as removing itself as an event listener. The shutdownSnapin() method is implemented as follows:
public void shutdownSnapin()
{
.
. /*Shut down listeners, etc.*/
.
}
A number of methods that serve as utility functions are defined in the Shell interface. Some of these are for general use in that they provide ways to interact with the shell, while others are designed for interacting with other snap-ins or are restricted in their use to only certain snap-in types. For further information on these available shell methods, go to the Shell interface in the API Reference Guide.