Appendix A. A Tour of Existing Modules

Many of the modules in NetBeans supply Service Provider Interfaces (SPIs) you can use to implement your functionality much more quickly. A good example of this is the XML set of modules that provides a variety of different types of support for XML.

Also, you may often find yourself implementing functionality that resembles something another module does, and having a template for how to do that is a very good way to avoid making mistakes or reinventing the wheel.

Modules That Expose Functionality You Might Need

While we’ve endeavored to provide a good start for building your own modules for NetBeans, there’s nothing like learning from the experience of someone who has solved the problem you’re facing. And since all of the modules mentioned in this appendix are open source and available in source code form on netbeans.org, there is nothing preventing wholesale borrowing of useful code and techniques from modules that do something you need to do. The following sections provide some useful sources of examples.

The XML Modules

As XML is used more and more in business and computing, it will be more and more common for modules integrating with NetBeans to either use XML internally in one form or another or handle specialized editing or construction of specific types of XML documents. The XML (http://xml.netbeans.org/) project is where to find detailed documentation on these modules. Support for XML in NetBeans is factored into a set of modules that address different needs for working with XML:

TAX Library

Not to fear, no fees will be assessed. TAX stands for “Tree API for XML.” This library is what other XML support modules use for getting a structural representation of XML and DTD documents. It can handle dynamically updating them programmatically, firing events on changes, and more. The model is similar to DOM, but more specialized for a development environment.

XML Core

This module provides the basic support for parsing XML documents into the TAX library’s representation of them, and is responsible for creating the basic XML data object type in NetBeans. The XML Core module contains provisional implementations of what will eventually become NetBeans’ standard APIs, but currently are still under revision.

Tools

These are XML productivity tools, including such things as tools for generating a DTD from an XML document.

Catalog

This module allows NetBeans to use entity catalogs.

XML Text Editor

Provides an editor implementation with syntax highlighting, abbreviation support, and code-completion support for XML documents.

XML Tree Editor

Provides a structural visual editor for XML and DTD documents and filtering to customize how the document tree is presented (for example, showing or not showing whitespace elements).

CSS

Provides basic support for editing CSS (Cascading Style Sheet) documents in NetBeans.

The interesting thing about these modules is that you will be able to register a specific DTD or XML namespace that will represent your module’s kind of XML content and register a data loader for that type of data. So a module can implement domain-specific behavior for XML documents, using the Looks infrastructure. For example, viewed as a text file, a Tomcat deployment descriptor looks much more intimidating than it needs to in order to expose its user-relevant characteristics. With a look registered for deployment descriptors, users will be exposed only to the relevant information, but if they just want access to the raw structure of the XML file, they just change the look being used on its property sheet. As of this writing, the API to the XML modules permitting this kind of customization is still under development.

The Editor

The editor is implemented in two parts:

  • A drop-in replacement for Swing’s editor kits.

    This is a set of Swing EditorKit implementations and base classes designed to make it easier to build your own editors. Programmatically, they behave similarly to Swing’s built-in editors (and so can be used in stand-alone applications), but they have far more features and a mature SPI for building support for new content types. The JSP module can add JSP syntax-coloring support, and so on. This SPI, in turn, consists of a few different parts:

    • Editor kits for different content types.

    • Infrastructure for specifying a lexical analysis engine for a content type (with some support for using ANTLR, a popular open source parser generator). The new lexer module is intended to make this infrastructure more general.

    • Syntax coloring based on the tokenization provided by the lexer.

    • Formatting and indenting text based on the tokenization.

    • Code completion—you can plug in an engine that can supply completions based on cursor position and context. Compound documents in multiple languages, such as HTML with embedded JavaScript, can be supported as well.

    • Editor-specific base classes for actions that allow easy access to the editor’s content. For example, adding a keyboard shortcut to line wrap a paragraph could be accomplished using one action subclass.

  • A NetBeans-specific SPI allowing modules to integrate their own content types that uses the first half as a library. It supports the following things:

    • Registration of editor kits by MIME type.

    • Provision of system options for a new kit. These system options enable the user to customize the editor’s visual appearance. For example, fonts and colors used in syntax coloring can be changed, printing behavior can be refined, abbreviations can be added, and keyboard shortcuts can be rebound.

    • Creation of new NetBeans “indentation engines,” selectable by MIME type. This is based on the text formatting ability in the generic library.

    • The ability to add a toolbar appropriate for a content type. For example, Java sources can display a small toolbar with a method/field picker.

Version Control—the VCS Core Module

The VCS Core module handles most of the dirty work of integrating version control systems with the NetBeans Filesystems API. It handles caching, user interface, and versioning-specific submenus. Combining the SPI exposed by this module with the annotation capabilities in the Filesystems API for modifying a file’s display name and icon to indicate its status gives you everything you need to (fairly) painlessly integrate a version control system. For examples of its usage, investigate the sources of the JavaCVS or Generic VCS modules.

The Generic VCS module allows you to integrate with any command-line version control system without writing Java code, but by creating a profile for that version control system that includes commands and the syntax for issuing them to the system, along with regular expressions for parsing the output of those commands into results meaningful to NetBeans. This can also be an effective way to integrate a version control system, but often a tighter integration can perform better and be more effective at exposing the particular features of your version control system. You can incrementally tighten an integration using Generic VCS by writing small Java classes to handle particular commands. The resulting profiles can be packaged and distributed as first-class modules, for example, using the Update Center.

RemoteFS

Similarly to VCS Core, this module defines an SPI that makes it more convenient to build filesystem support for types of filesystems that store data remotely. It is currently primarily documented in Czech, however. For an example of its usage, see the FTPFileSystem implementation in the same module, which uses this support to provide filesystem support for FTP servers.

The Ant Module

The Ant module provides an SPI that allows other modules to register tasks that should be run from inside the NetBeans environment. For example, the Open APIs Support module uses this hook to implement uninstalling and reloading a module as an Ant task. Tasks thus registered are then available to any Ant script run from inside NetBeans.

The Java Module

Integrating with the Java module is somewhat problematic—in practice, it is widely and frequently done, but what is exposed by the module as official API/SPI is fairly minimal. The Java module exposes an interface that other modules can use to hook into the creation process of source element Nodes, allowing control over both the presentation and the properties of those Nodes. For examples of this usage, see the JavaBeans Support module (http://beans.netbeans.org/). The Form Editor, CORBA, and RMI modules go further to extend JavaDataLoader and JavaDataObject in various ways.

With the introduction of the Metadata Repository, the Java module is slated to be rewritten to use this technology and the Looks infrastructure. This rewrite will not necessarily mean any significant differences in appearance or behavior, but a much more standardized and extensible infrastructure for adding features such as JavaBeans, GUI form editing, and so on. This work is in progress at the time of this writing, and we refer you to the documentation at http://java.netbeans.org/, the Javadoc of the sources, and the public mailing lists for up-to-date details. The authors of this module are on the mailing list; if there is something you need to do involving integration with the Java module, that is the place to go.

While all this may sound scary, bear in mind that at the time of this writing, more than 30 companies are shipping modules, four distributions of NetBeans as a Java IDE, and numerous applications using the NetBeans Platform. Every step possible will be made to ensure backward compatibility or document changes module authors will need to make. For cases such as extending the Java loader, which is not an official API, module authors may need to make some changes.

Debugger Core

This module provides a substantive SPI by which you can integrate different debuggers. There is additionally the JPDA Debugger module, which a few modules rely on, but the primary point of integration is the Debugger Core module.

J2EE Server

This is a pure SPI module—it does not, by itself, expose any user-level functionality or actions. It allows you to plug in integrations with new J2EE servers and register information about the deployment descriptors required to deploy objects to such servers. You can also add properties to an EJB specific to a given application server, or create execution services specific to that server, which will integrate smoothly with existing support for EJBs and web applications. To integrate support for an application server, write code to the SPI of this module and create a module that provides deployment ability for that server.

Form Editor

The Form Editor module is as problematic as the Java module to integrate with. There is extensive and powerful support for integrating new layout managers—this can be an entry point for integrations in that it allows you to define the semantics of drag-and-drop into forms, constrain what types of components can be added, and define customizers for a form layout. Adding new beans to the Component Palette is also straightforward.

For deeper integration, such as defining an entirely new kind of form, there is no specific API. Such support will need to be written from scratch, but the Form Editor sources can act as a guide for doing this effectively.

HTTP Server Module

Among its other functions, this internal server allows other modules to add their own Java servlets. Such servlets will be run inside the NetBeans VM, which can be useful for presenting some aspect of a module’s functionality over HTTP.

Classfile Reader Module

This module is used by other Java-related support modules. Originally, to handle Java classes without associated sources, NetBeans relied on loading the classes into the NetBeans JVM and introspecting them. This technique is usually effective, but undesirable: poorly-behaved classes might have static blocks that run unknown initialization code.[26] The Classfile module provides a lightweight structural parser for Java bytecode, which is now used in preference to introspection and can provide information on deprecated methods and more.

The Metadata Repository—a Whole Host of APIs

As we write this appendix, the Metadata Repository is still being finished, so it is difficult to give specifics on it. The fundamentals are that, given a model for a programming language and a parser for that language, the Repository is capable of processing sources and generating metadata for those sources. See Appendix D for more information.

Socket-Based Editor Support—the External Editor Module

The External Editor module is used to replace NetBeans’ internal editor with the popular Unix-based editors VIM or XEmacs. This is accomplished by creating a Swing EditorKit implementation that is a wrapper for a TCP/IP socket and that defines a protocol by which an external editor can interact with NetBeans. For those interested in integrating editors not written in Java or editors that will run on a machine remote to the one on which NetBeans is running, this not-for-the-faint-of-heart module provides an example of how to do it.

Those wishing to tightly integrate a new external editor into NetBeans will be able to implement the remote side of a text-based socket protocol defined in this module.

Incidental APIs, Utilities, and Extensions

The following modules are useful for common problems and tasks in programming NetBeans. Each helps you avoid repetitive coding, especially when someone has solved the same problem before.

The Utilities Module

The Utilities module is a grab bag of useful classes, APIs, and convenience implementations of miscellaneous interfaces. Components worth mentioning here are as follows:

Data loader for .url files

If you need to provide URL links from a menu or toolbar, you just create a file with the extension .url containing the desired URL. A suitable menu item (or toolbar button) will be created that displays the URL in the IDE’s web browser (internal or external). You can control the menu item or button’s appearance by giving a localized display name and icon for the .url file.

.group files

Allow a single file to act as a pointer to a collection of files. In particular this is used to implement group templates. If you have used some of the Open APIs Support templates mentioned in this book, you may have noticed that a template might cause more than one file to be created. For example, when you use the CallableSystemAction template (from the Actions API), an icon and a resource bundle are created along with the action class. .group files make this behavior easy to implement without the need to write a custom template wizard iterator.

API Extensions (openidex)

This library contains unofficial or proposed extensions to the Open APIs—rather like the utilities module except that its contents are not necessarily convenience classes for module authors, but things that have the potential to eventually become better supported APIs. A number of things currently present in openidex will eventually be split out into additional modules, and the current components deprecated but present for a few generations of NetBeans and eventually removed. What is useful there currently is:

Search API

Permits objects to be searched. The API in org.openidex.search.* consists of SearchType and SearchGroup. SearchType is a service and defines one way of searching, such as by object type or VCS status; the user can customize search types, save them, and reuse them. SearchGroup permits different kinds of objects to be searched—for example, data objects or uninterpreted file objects.

A separate SPI to help you create new search types more easily does not exist; however, some examples of concrete search types can be found in the Utilities module, which also provides a general UI for searching.

Old Looks API

An older version of the Looks API, used in NetBeans 3.3, is kept in org.openidex.nodes.looks.*. Newer code should, however, use the revised Looks API and SPI, available as a separate module for NetBeans 3.4.

Modules That Make Good Examples for Things You May Need to Implement

While we’ve written this book as a task-based guide to working with the Open APIs, one of the best ways to become quickly and deeply familiar with an API set is to modify existing code. And for most problems you’ll need to solve in building modules for NetBeans, you will usually find modules that have had to solve problems similar to yours. Let this section be a guide to finding some examples for things you may need to code.

Annotations and Dynamic Editor Tool Tips—the Ant Module and the Debugger Core Module

Both of these modules do non-trivial work with annotations: marking up lines in the editor with alternative font styles or icons to indicate something to the user. These modules are worth a look if your implementation needs to add this type of functionality.

Adding Information to the View of Java Sources—the Beans Module

The Beans module (the one that creates the Bean Patterns node underneath the node for a Java source file) provides a good example for module authors writing code that needs to add functionality available on Java sources. Its implementation is likely to change with the pending revisions to the Java module, to use the Looks infrastructure rather than its current approach, but it provides an effective example of interacting closely with the Java module and integrating new functionality.

Adding a Debugger Type—the Applet Module

The Applet module adds support for applet debugging in NetBeans. For a simple example of integrating a new debugger type, it is quite effective.

Multiplexing DataObjects and Complex Cut/Copy/Paste Support—the Properties Module

The Properties module (which handles Java resource bundles) does some of the most complex things with DataObjects of the available examples. A set of .properties files related by locale form a single DataObject with a subnode for each locale. The various locale files for a given properties object need to sometimes be treated as a single entity, and sometimes as separate entities. For example, a graphical table view displays all locales side-by-side, while individual locale files can also be opened as text. You can cut and paste the entire object as a whole or manipulate just one locale file within it.

Working with Network Protocols to Access Files—JavaCVS and RemoteFS

For anyone integrating a new kind of filesystem storage, the JavaCVS and RemoteFS modules demonstrate the range of available possibilities.

Domain-Specific XML Support—the Tomcat and Ant Modules

If your module deals with XML files, but is only interested in those that conform to a specific DTD or schema or other constraint, these modules provide excellent examples. The Ant module provides support for managing Ant build files. It hides unnecessary details of the XML and makes it easy to create new tasks and launch them from within NetBeans. The Tomcat module provides support for Tomcat deployment descriptors (among other things).

In NetBeans 3.3, these modules internally rely on ad-hoc manipulation of the XML document structure, so they should be treated as examples of possible UI rather than implementation. For 3.4 or 4.0 the XML modules’ infrastructure should be used to simplify the implementation and improve features and robustness.

Stretching the Limits—the Web Modules

In the immortal words of Mr. Glick, “The most ill-advised uses of the Datasystems API are in the Web modules. All the things that make API developers hold their heads and groan are done routinely by them.” These modules are definitely a source of non-trivial examples of just how far the limits of NetBeans can be pushed, considering DataObjects that map their own filesystems, replace root directories, and so forth.

Many of these unusual use cases are actually symptomatic of some limitation in the APIs. For example, the current APIs identify the user-level classpath with the roots of mounted filesystems, which forces supports for web applications to mount many libraries just to ensure their existence in the classpath. This kind of problem should be solved in the future with a more sophisticated API for projects, currently in planning. See Appendix D for more details on how these issues will be addressed.

Complex Syntax Coloring—the JSP Module

The JSP module provides a great example of multi-language mixed-mode syntax highlighting and code completion, where a user edits a document that is in multiple languages and the editor needs to highlight and provide appropriate formatting, abbreviations, and syntax highlighting for multiple language contexts within a single document.

Multi-Stage Compilation—the JSP, RMI, and CORBA Modules

The JSP module lets you plug in an arbitrary Java compiler, but must first run a JSP preprocessor to generate the servlet code that will be fed to it as Java source. RMI takes a similar approach in almost the reverse order—an RMI source is a remote interface, which needs to be compiled and then have a postprocessor run against the result to generate client and server dynamic stubs. Both of these modules provide good examples of pipelining an existing compiler in a more complex build process. The CORBA module is also a good example of this.

Bridging to an Entirely Different Build System—the Ant and Makefile Modules

These modules provide excellent examples for cases where you need to perform a build process that walks and talks like NetBeans’ notions of compilation but that relies on none of the existing infrastructure. The user invokes the UI for compilation in NetBeans, but on the back end an entirely different infrastructure is used.

Also do not overlook the cpp and cpplite modules that help the user create and run the C/C++ makefiles traditional on Unix systems.

Use of the Compiler Infrastructure for Non-Compilation Tasks—the JAR Packager Module

You can compile a recipe for a JAR file into an actual .jar archive using the JAR Packager module. This is a process that bears enough resemblance to a compilation process that it makes sense for the user (and for the developer of the module) to fit it into the same paradigm—you have a set of sources and a result that represents those sources transformed into a different type of file.

Successfully creating an archive requires that the contents of that archive first have associated processing applied to them, such as compiling Java sources to .class files. Failure at any stage is indicated to the user so that the problem can be corrected. If these stages complete, the archive will then be generated.

Here the final JAR generation stage is unaware of what type of compilation or processing is done to the content files—Java files use their associated compilers, as do RMI interfaces, and so on. The Compiler API is used to communicate between the JAR Packager module and the compilers associated with the content files.

Execution—the Applet and JSP/Servlet Modules

Each of these modules provides an example of performing user-invokable execution of a certain type of object that involves special initialization of an environment into which those objects need to be deployed, before the deployment itself. In the case of JSPs, a Tomcat server must be launched and a JSP load request sent to it. For applets, the applet viewer or a remote browser must be launched, which may also involve preparing a custom security policy file.

The I18N module also allows you to launch applications using the locale of your choice. This is a nice example of a very simple but useful executor.

Custom Hyperlinking in the Output Window—the Ant Module

The Ant module provides a good demonstration of the use of annotations for hyperlinking in the Output Window—for an example of this, create an Ant build file, intentionally introduce syntax or semantic errors into it, and then run it. The Output Window will indicate the location of the error with a hyperlinked message. You can double-click the message to navigate to the error in the editor, where you will see an error icon in the editor’s gutter with a tool tip giving the error message.

Specifying Windows, Workspaces, and Components Using XML—the Core Window System and the Form Editor Module

The Window System API specifies how to define workspaces, what windows should appear on them, and what components should live in those windows, all using module layers. Since NetBeans has default components such as the Explorer, the best example of how to specify these things is to look at the core window system, which uses XML to define the default contents of NetBeans’ workspaces and their windows. The Form Editor module is also a good example, since it does an interesting job of docking components together.

Complex Work with MIMEResolvers and Multi-File DataObjects—the CPP Module

The CPP module provides support for editing, compiling, and executing C++ (as well as C and FORTRAN). On Unix systems at least, there is not a simple naming convention for files used by these languages that can permit easy file classification. For example, standard C++ headers now have no extension (stdio rather than stdio.h). ELF object files are often named *.o but not always, and linked executables traditionally have no extension.

To enable NetBeans to intelligently handle all such object types, a complex MIMEResolver is used to classify files by name and content and assign MIME types accordingly.

Completing the process of mapping raw file data on disk to structured DataObjects, complex data loaders know how to associate source files with the object files they compile to.

Cut/Copy/Paste—Data Transfer Support for Complex Elements—the Ant and Java Modules

The Java module allows you to use cut/copy/paste for manual refactoring of Java sources and provides hooks for such things as redefining package declarations when a source file is pasted into a different package. If your module supports a structural data type that may need some modification if its context is changed, look at this aspect of the Java module for an example.

The Ant module contains a straightforward implementation of the common data transfer operations within the context of structurally constrained XML files.

Interconversion between Different Types of Clipboard Contents—JNDI, CORBA, and RMI

Each of these modules provides a runtime interface to interact with remote objects on a live server, and each of them also provides a means for you to copy an entity in the Explorer window that exists on a remote server to the clipboard. The goal of such functionality is that what the user pastes into the editor from this operation is Java source code that will produce a reference to that remote entity. So this provides a good example of copying something to the clipboard, while performing a complex conversion to data meaningful for the paste context.

Integrating Other Programming Languages—the C++/Fortran, Scripting, and WebL Modules

While NetBeans may have started its existence as a Java-based IDE for Java, it is no longer exclusively for Java. The ongoing introduction of the Metadata Repository will result in a standardized technique for generating Java classes to support a language within NetBeans from an abstract metamodel of that language and a parser for the language.

Nevertheless, for building support for a new language against the current infrastructure, these modules can serve as an excellent guide, and many of the things they do to integrate tools for working with those languages will remain viable even when MDR is used for handling the language metadata. You can find examples of language-specific compilation and execution tools, syntax coloring, and more.

Fancy Footwork with Nodes—the Java Module

The Java module does some of the most complex operations with Nodes to be found in the NetBeans source base. This includes providing custom properties and context-sensitive property editors, copy and paste between different types of containers, customizable sorting and display formats, and accepting factories for other modules to create additional child Nodes of a module-provided Node.

Adding Nodes to the Runtime Tab in the Explorer—the RMI, CORBA, JNDI, and Database Explorer Modules

The Runtime tab of the Explorer window is generally used for representing transient internal data and live remote servers and objects residing on them. Generally, server-oriented modules add Nodes here for the type of server they support, which have context actions allowing the user to create and manipulate subnodes representing live servers.

The Bare Essentials of Non-Data-Driven Nodes—the System Properties Module

This module also adds a node to the Runtime tab in the Explorer window, displaying the Java system properties set in the VM that NetBeans runs in. It does a number of common tasks with Nodes: creating a hierarchy of subnodes lazily; refreshing Nodes based on internal changes; displaying properties in the property sheet, permitting the user to add, delete, and rename nodes; and so on. Its attraction as an example is that the data it represents is rather simple: the standard Java calls System.getProperties( ) and System.setProperty( ) suffice to manipulate it. For this reason, almost all of the code can serve as an example of using Nodes, without much distraction.

Wizards—the CORBA, Java, and New Module Wizard Modules

The CORBA Wizard provides a general, straightforward example of how to build a wizard using NetBeans’ infrastructure. On the other hand, the Java module provides an example of a custom wizard iterator that extends the New Wizard. Creating a wizard well may require non-trivial logic for when the user can continue and for determining the subsequent sequence of steps based on the user’s prior choices. This module provides a good example of such logic.

The New Module Wizard (apisupport/lite in sources) is also a good example for performing complex logic to determine whether the user may proceed and of using a wizard to create not one but a suite of resulting objects all of which are determined by the user’s choices in the wizard.

Embedding Property Panels into Wizards—the Java Module

When you create a new Java object from a template, you will find a number of additional panels in the New wizard that are not present if you are creating, say, a plain text file. These panels are added by the Java module and allow you to specify such things as the superclass for your class and what initial fields or methods you want to create or inherit.

Complex Explorer Views—the Debugger Core Module

Probably the most complex window composed of explorer views in the NetBeans IDE is the Debugger window, which offers a set of panes for such things as sessions, breakpoints, and watches. If you need to expose complex but interconnected trees or lists of data to the user, this implementation can provide a good example of how to do that. It also demonstrates complete configuration of a window system workspace geared to a certain task (as does the Form module).

Enabling/Disabling Sets of Actions Based on Context—the VCS Core Module

The VCS Core module provides a toolbar for versioning-related operations that need to be active only when the user is interacting with version-controlled sources.



[26] Any code run in-VM from user classes is subject to a security manager. But this just changes the problem from a security hole to an annoyance, when SecurityExceptions are thrown just because you looked at a class file with a static block.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.66.156