Supplying Tag Library Metadata for Apache MyFaces Tomahawk |
In this tutorial we will write a plugin that supplies metadata that will be used when editing a JSF JSP page that uses the tag library for the Apache MyFaces Tomahawk JSF component library.
This tutorial will walk through the process of writing a plugin that provides additional functionality while editing JSF JSP pages that use the tag library for the Apache MyFaces Tomahawk component library. By supplying metadata for this tag library, code-completion and validation functionality becomes available for attributes of the Tomahawk tags. This plugin will not aim to provide a complete set of metadata for the library, it will simply lay the groundwork and explain the general concepts.
It is assumed that the user is already familiar with the use of JSP tags and basic editing of JSP pages. It is further assumed that the user is familiar with adding tag libraries to web projects and correctly specifying their use in JSP pages.
First we will need to create a new Plug-in Project in order to extend the necessary extension point to supply your metadata. Select File > New > Project... to open the New Project dialog, select Plug-in Project and click Next >.
Provide an appropiate value for Project name, uncheck Create a Java project (in this example we do not require this to be a Java project, although a Java project is perfectly valid and in some cases may be desirable) and click Next >.
Provide appropriate values for Plug-in Properties and click Next >.
Uncheck Create a plug-in using one of the templates and click Finish to complete creation of the plug-in project.
In the Package Explorer, double-click MANIFEST.MF to open it in the Plug-in Manifest Editor (if it is not already open as a result of creating the project in the previous step).
In the Plug-in Manifest Editor, select the Dependencies tab and click the Add... button to add org.eclipse.jst.jsf.contentmodel.annotations as a required plug-in.
In the Plug-in Manifest Editor, select the Extensions tab and click the Add... button to add org.eclipse.jst.jsf.contentmodel.annotations.annotationFiles as an extension.
Still in the Plug-in Manifest Editor and on the Extensions tab, right-click org.eclipse.jst.jsf.contentmodel.annotations.annotationFiles and select New > annotationFile. Set the uri to http://myfaces.apache.org/tomahawk and the location to metadata/apache_tomahawk.xml (the value of location is the plugin-relative location of the metadata file that we will create in a later step and so is arbitrary, while the value of uri must correspond with the tag library's specified URI). For this example, we will not be specifying values for the optional properties locator and parser. Save your work and close the Plug-in Manifest Editor if you desire.
Create a new folder and XML file, such that from the plug-in project root you now have the file metadata/apache_tomahawk.xml (which matches the value of location as set in the previous step). Double-click this file to open in the XML editor.
Working in the XML editor, paste the following XML into the metadata/apache_tomahawk.xml file. We now have a minimal, legal (although not yet incredibly useful) metadata file.
<?xml version="1.0" encoding="UTF-8"?> <p:grammar-annotations xmlns:p="http://org.eclipse.jst.jsf.contentmodel.annotations/grammarAnnotationSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://org.eclipse.jst.jsf.contentmodel.annotations/grammarAnnotationSchema ../../org.eclipse.jst.jsf.contentmodel.annotations/schema/grammar-annotations.xsd"> <cm-element name=""> </cm-element> </p:grammar-annotations>
In this example, we will be providing metadata for Tomahawk's popup tag. To begin, we need to specify in our metadata file the name of the element (tag) that we are annotating. We do this by simply setting the name attribute of the cm-element element to popup, as seen below.
We continue by specifying properties for the popup tag's attributes. We do this by adding cm-attribute elements to our XML file. We will start with the displayAtDistanceX and displayAtDistanceY attributes, the values of which must be an integer. We specify this by adding the appropriate cm-attribute and property elements to our XML file, as seen below. (The "org.eclipse.jst.jsf.taglibprocessing.attributevalues.IntegerType" runtime type is one of the types pre-defined in the org.eclipse.jst.jsf.taglibprocessing plug-in.)
We continue by specifying appropriate cm-attribute and property elements for the closePopupOnExitingElement and closePopupOnExitingPopup attributes, the values of which must be boolean, and the default value of each is "true". As seen below, we use the "org.eclipse.jst.jsf.taglibprocessing.attributevalues.BooleanType" runtime type to specify this.
To complete the metadata for this example, we will address those attributes which have the same meaning no matter which element upon which they are defined. Examples are id and binding. In these cases, rather than specify the metadata for every element, we can specify the metadata once for any element by using "*" as the value of the cm-element's name attribute. As seen below, we now do this for the id and binding attributes using pre-defined runtime types and properties.
This plugin can now be packaged and deployed to Eclipse in order to get advanced editing capabilities (e.g. content-assist and validation) for the attributes of the elements of the Tomahawk tag library that we have defined here. Obviously, this example only covers part of the tag library, but hopefully serves as a starting point for interested developers.
For reference, the contents of the completed example metadata/apache_tomahawk.xml file follows.
<?xml version="1.0" encoding="UTF-8"?> <p:grammar-annotations xmlns:p="http://org.eclipse.jst.jsf.contentmodel.annotations/grammarAnnotationSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://org.eclipse.jst.jsf.contentmodel.annotations/grammarAnnotationSchema ../../org.eclipse.jst.jsf.contentmodel.annotations/schema/grammar-annotations.xsd"> <cm-element name="popup"> <cm-attribute name="displayAtDistanceX"> <property name="attribute-value-runtime-type"> <value> org.eclipse.jst.jsf.taglibprocessing.attributevalues.IntegerType </value> </property> </cm-attribute> <cm-attribute name="displayAtDistanceY"> <property name="attribute-value-runtime-type"> <value> org.eclipse.jst.jsf.taglibprocessing.attributevalues.IntegerType </value> </property> </cm-attribute> <cm-attribute name="closePopupOnExitingElement"> <property name="attribute-value-runtime-type"> <value> org.eclipse.jst.jsf.taglibprocessing.attributevalues.BooleanType </value> </property> <property name="default-value"> <value>true</value> </property> </cm-attribute> <cm-attribute name="closePopupOnExitingPopup"> <property name="attribute-value-runtime-type"> <value> org.eclipse.jst.jsf.taglibprocessing.attributevalues.BooleanType </value> </property> <property name="default-value"> <value>true</value> </property> </cm-attribute> </cm-element> <cm-element name="*"> <cm-attribute name="id"> <property name="attribute-value-runtime-type"> <value> org.eclipse.jst.jsf.taglibprocessing.attributevalues.ComponentIDType </value> </property> </cm-attribute> <cm-attribute name="binding"> <property name="attribute-value-runtime-type"> <value> org.eclipse.jst.jsf.taglibprocessing.attributevalues.ComponentBindingType </value> </property> <property name="runtime-return-type"> <value>javax.faces.component.UIComponent</value> </property> </cm-attribute> </cm-element> </p:grammar-annotations>