JavaScript Library Manager Support in NetBeans 6.5
Terminology:
- Library definition: consists of the name of the library, the library type, a pointer to the library archive volume(s).
- Library reference: a reference to a library object, especially used when a project consumes a library.
- Actual Library: the actual set of all the files belong to library in an archive, excluding any metadata that might exist. It is interchangeable with raw library.
Goals & Strategies
- JavaScript libraries are to be registered and managed in NetBeans using the NetBeans Library Manager mechanism.
- A number of 3rd party javascript libraries will be pre-packaged as NetBeans modules.
- Some of 3rd party libraries will be bundled with the IDE standard distribution and others will be made available on the stable update center. A more detailed list of these libraries to be bundled can be found in this plan .
- JavaScript libraries can be consumed in Web, PHP, or Ruby on Rails projects by extracting the artifacts into the user's project.
- Additional metadata may need to be defined to express addtional support for things like:
- Public vs. Private files in the JavaScript libraries. The private files may not be considered by the indexing mechanism
- Location of documentation files in SDoc format etc.
- The metadata formats and structure will be documented so that they can be put together by the JavaScript library developers by hand. In the long run we should look into Wizard like mechanisms to introspect the JavaScript libraries and generate the metadata with JavaScript Library developer's assistance.
- In the future releases, intelligence to interpret the metadata, primarily to aid in the consumption of widget libraries, will be added to the NetBeans JavaScript Library consumption support.
Proposal
In order to achieve the goals stated above, the implementation includes:
- Defining the libraries with the proper information and registering them in the IDE
- Consuming the libraries in a Web, PHP or Ruby on Rails project.
JavaScript Library data structure
A javascript library type, based on the NetBeans Library Manager framework, contains only 1 'scriptpath' volume type. This volume is used to store javascript library archives, which are expected to be .zip archives. A typical archive would consist of the following if being prepackaged with the IDE distribution:
- the actual javascript library contents
- library.properties. This file contains properties that provide information related to library consumption. The following properties are to be implemented:
LibraryRoot=<path from archive root to library folder>
DefaultLibraryDir=<default relative destination folder in projects that consume the library> (optional)
The LibraryRoot property is used to determine the actual location of the library files. This is used by the Library Manager when a library is consumed to ignore unneeded zip artifacts (e.g. from jmaki) and to shorten the path to the library when extracted (e.g. resources/some_library/some_library_version_1.0/a_file could be extracted to $projectdir/web/a_file if desired).
Samples and documentation may remain in the same archive since these usually are embbeded deep in the actual library structure. The documentation includes .sdoc and jsdoc files. The .sdoc files are used by the javascript editor and can be loaded in based on their .sdoc suffix. Some of these files may be stripped from the libraries that are bundled with the IDE.
Registering JavaScript Libraries in NetBeans
There are 2 ways to register a javascript library in NetBeans:
- Packaging in an NBM which basically consists of a NetBeans Module wrapper for the library archive, its library definition and the layer file registration information. This can then be installed via the Plugin Manager and will appear automatically in the Libraries manager automatically upon a successful installation.
- Providing the library definition from within the IDE. This is done in the same way as Java class libraries: go to the Library Manager from Tools->Libraries, select 'New Library...', change the library type to 'JavaScript', and add the relevant zip files from the 'Add Zip...' dialog.
Library consumption
To consume a JavaScript library in a project, the contents of the library are extracted into the user's project location.
The existing 'Tools->Add JavaScript Libraries to Project' and its dialog in Milestone 1 will be replaced with the following functionality:
When the user brings up the project's Properties dialog, a new JavaScript Libraries category will be present in the list on the left side of the dialog. When this category is selected, the following customizer will appear:
When choosing Add Library, there will be a dialog that lists all the available libraries to be added:
This list of libraries includes only JavaScript libraries that have not already been added to this project. After the user selects the libraries that he wishes to add to his project and presses the OK button, the library target location dialog appears for each selected library:
The default location for each project type is:
- For Web projects, the location is web/resources/<library name>
- For Ruby on Rails projects, the location is public/resources/<library name>
- For PHP projects, the location is $src-root/resources/<library name> (where $src-root is defined by the PHP project)
The specified location must be under the web folder of the project or under the project folder. If the library.properties file exists and provides a LibraryRoot property, the files are extracted as specified above; otherwise, all of the contents of the zip archives provided by the library definition are extracted.
If the destination directory contains some files that will be overwritten by the library extraction, a warning dialog appears. If the user selects "No", then the library is not added to the project. After the user selects "Yes" to add the library, every file that is to be overwritten brings up a dialog providing options to handle the collision (Yes, No, No to All, Yes to All).
Library removal
When one or more libraries are selected in the libraries customizer and the 'Remove' button is pressed, the following steps are executed for each selected library:
- The library definition is removed from the project's metadata, which in turn causes the reference to disappear from the list of JavaScript libraries in the project.
- A dialog appears, asking the user if the library's files should be removed as well. If the user selects "No", no further action is done.
- All files and directories extracted or created during the library consumption are removed. This includes the folders that may have been created when the user selected a destination folder for the library.
Unresolved References
Since the library artifacts are present in the project sources, there is no "Unresolved References" check for JavaScript libraries, as opposed to library consumption for Java class libraries. Instead, the JavaScript Libraries customizer in the project's Properties dialog displays relevant information regarding the status of each consumed library. The following error conditions are displayed:
- Unresolved library reference - Occurs when there is no library definition for a given library reference in the project.
- Missing Sources - Occurs when there are no files associated with the library reference in the project (relative to the location specified by the user).
When the library references are in these error states, the Remove action removes the library reference from the project without deleting any project source files.
Optional JavaScript Library Support
Like other IDE plugins, the JavaScript Library Manager module can be uninstalled. When this occurs, the JavaScript Libraries customizer in the project's Properties dialog disappears. Since the library artifacts are part of the project sources, no additional handling is needed for projects to build and run correctly.
APIs
The following Library API can be used to obtain the javascript library:
- Get all libraries first: LibraryManager.getDefault().getLibraries()
- Get only 'javascript' type libraries: Library.getType().equals("javascript")
- Get the 'scriptpath' volume content: Library.getContent("scriptpath"). This returns a URL to the actual archive zip file. The content of the zip file can then be extracted into a relative project location.
- Get notified when a library is added / registered in the Library Manager: LibraryManager.addPropertyChangeListener. Consider using WeakListeners to avoid memory leaks.
- Add a library: LibraryManager.getDefault().addLibrary()
(Reference: http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-project-libraries/org/netbeans/api/project/libraries/LibraryManager.html)
Issues not solved for NetBeans 6.5:
- How to manage public vs. private files in a library? This appears to be have originated from performance concerns, but the JavaScript editor appears to prune code completion results now, possibly making this requirement unnecessary.
- Widget library consumption