JSF Central - A Proposal for Design-Time Metadata for Java Server Faces Components
JSF Central

 
 Home 
 
 Products 
 
 Articles & Books 
 
 Resources 
Community Proposal
 
A Proposal for Design-Time Metadata for Java Server Faces Components
by Ryan Pollock, Jeff Stephenson and Adam Winer (Oracle Corporation)
25 Aug 2004 01:30 EDT

This document is a starting point for a community discussion that will hopefully result in a standard mechanism for associating design-time metadata with Java Server Faces components. Existing sources of grammar and metadata information are examined, and a strategy for providing additional design-time metadata is proposed.


Interested in discussing this proposal? Share your opinion in the official JSF forum

Contents

I. Introduction
II. Proposed Solution for Additional Design-Time Metadata
  a. Adding Metadata to Faces-config.xml
  b. Accessing Metadata when using JSP
III. Using Faces Metadata
  a. Extending the Metadata Language
IV. Metadata in Action
V. Conclusion

I. Introduction

Tools require both grammar and metadata information for Java Server Faces (JSF) components in order to provide a polished design-time experience. Grammar information, such as the set of available components and what attributes exist on those components, is used by tools to guide the user towards valid editing operations. While grammar information can help the tool support the basic operations for creating and manipulating components, metadata can be used to enhance the design-time experience in a variety of ways. Design-time metadata is perfect for simple customizations like changing what name or icon a tool displays for a component, but can also be used to arrange components or attributes into groups, or even provide information on common design patterns associated with a component. This document examines the existing sources of grammar and metadata information for JSF components, and then proposes a strategy for providing additional design-time metadata.

The problem of how design-time environments should support Faces components is complicated by JSF's flexible run-time architecture. The most common way to use JSF technology today is through JSP tag libraries. Given that many tools already have some level of JSP support, it is tempting for a tool vendor to derive grammar and metadata information for JSF components solely from JSP tag libraries. After all, tag library descriptors declare tags and their attributes and even support standard metadata items for <description>, <display-name>, and <icon>. However, there are several problems with this approach. In JSP 1.2, the set of metadata expressible in a TLD cannot be extended. JSP 2.0 addresses this problem by supporting a <tag-extension> element, but providing metadata about attributes or facets in <tag-extension> is very verbose since you must partition the metadata into sections labeled with an attribute or facet name, which duplicates information contained in the faces-config.xml file. The larger and more fundamental problem with placing metadata in the tag library is that it is not the source of truth for JSF components. In fact, it is expected that most JSP tags for JSF components will be trivial wrappers for a given UIComponent and Renderer. Given the issues with storing metadata for JSF components in JSP tag libraries, and the fact that JSP is not the only way to use JSF technology, it is both more convenient and correct to store metadata in the <component> and <renderer> registrations in the relevant faces-config.xml file. TLD files are still necessary sources of grammar information when using JSF via JSP, since faces-config.xml files don't have the notion of tags or namespaces, but they need not contain all the design-time metadata.

Although the faces-config.xml language allows a component author to express a great deal of information about their components and renderers, it only has standard syntax for expressing a very minimal set of design-time metadata. Fortunately, the faces-config.xml language is designed with convenient extension points that can be used to hold additional information. Unfortunately, there is no standard that defines what syntax a component author would use inside of these extension points. While tool vendors could invent their own syntax for associating metadata with faces components, the hope is that the community of tool vendors and component authors can agree upon a standard mechanism. If there is a standard in this area, component authors will be able to provide metadata in one format that will work in all tools, and the end user will be in the ideal situation of being able to pick the tool they want to use independently from the component set that best meets their needs.

II. Proposed Solution For Additional Design-Time Metadata

The proposal below contains a set of metadata items that could be shared by JSF tools and a syntax for providing them in faces-config.xml. Following that proposal, additional issues when using JSF through JSP are discussed.

a. Adding Metadata to Faces-config.xml

The faces-config.xml language contains grammar information and a minimal set of metadata for components, attributes, properties, facets, and renderers. Each section below lists the information provided by the faces-config.xml language, and then proposes additional metadata items and a syntax for providing them.

Component Metadata
The <component> element inherently supports the following:
  • component-type
  • component-class
  • description
  • display-name
  • icon (which contains small-icon and large-icon)
Component types must be unique within the entire web application.

The proposal is to support additional design-time metadata for components in a new <component-metadata> element which would be used inside of <component-extension>. The following list of elements are proposed metadata items that would be used inside of <component-metadata>:

Item Name
Description / Use Case
accepts-child-components A boolean indicating whether the component allows child UIComponents. May be used to prevent drag and drops and in validation.
base-component-type A string that identifies the component type from which the component inherits properties and attributes (and their metadata).
component-family A string that identifies the component's family, equivalent to the result of calling getFamily() on a component instance . Perhaps used to identify a renderer commonly used for a component.
deprecated A string providing a reason why the component is deprecated. If there is a value, tags of this component type may be marked specially in the palette and context menus.
display-order An integer that may influence the display order for tags of this component type in a palette.
expert A boolean that indicates whether tags of this component type are for experts. Expert items may be hidden in the UI unless the user requests them.
favorite-property A string that is the name of this component's favorite property or attribute. Might be used to help identify a component in the UI.
group A string for categorizing tags of this component type. Might be used to group tags in a component palette.
help-topic A string used to identify a help topic for the component type.
hidden A boolean used to mark components as being hidden in the UI. Hidden components may not be available for creation at design-time.
preferred-child-components A space separated list of component types that are likely to be children of this component. Might be used for context-sensitive creation.
short-description A short description of the component. Perhaps used to provide descriptions in tooltips or status bar. A short-description typically differs from the standard description in that the short-description has been truncated.


Attribute and Property Metadata
The <attribute> element (defined inside of <component> and <renderer>) inherently supports the following:
  • attribute-class
  • attribute-name
  • default-value
  • description
  • display-name
  • icon (which contains small-icon and large-icon)
  • suggested-value
The proposal is to support additional design-time metadata for attributes in a new <attribute-metadata> element which would be used inside of <attribute-extension>. The following list of elements are proposed metadata items that would be used inside of <attribute-metadata>:

Item Name
Description / Use Case
attribute-values An enumeration of possible attribute values, that could be used by a property inspector or code insight.
deprecated A string providing a reason why the attribute is deprecated. If there is a value, this attribute may be marked specially by a tool, or a tool could give warnings if it is used
display-order An integer that may influence the display order of the attribute, for example in a property inspector.
expert A boolean that indicates whether this attribute is for experts. Expert attributes may be hidden in the UI unless the user requests them.
group A string used for categorizing attributes, for example in a property inspector.
help-topic A string used to identify a help topic for the attribute.
hidden A boolean used to mark attributes as being hidden in the UI. A tool might choose to not display hidden attributes, for example in a property inspector.
preferred
A boolean indicating that the attribute is likely to be set. A tool could feature this attribute more prominently.
property-editor A java.beans.PropertyEditor used to edit an attribute instance.
short-description A short description of the attribute. A short-description typically differs from the standard description in that the short-description has been truncated.
writable A boolean indicating that the attribute can be written to. Non-writable attributes may not be displayed, or editing might be disabled.

The set of metadata items for the <attribute> element are also appropriate for the <property> element. The proposal is to support the same metadata items above for properties in a new <property-metadata> element which would be used inside of <property-extension>.

Facet Metadata
The <facet> element (defined inside of <component> and <renderer>) inherently supports the following:
  • description
  • display-name
  • icon (which contains small-icon and large-icon)
  • facet-name
The proposal is to support additional design-time metadata for facets in a new <facet-metadata> element which would be used inside of <facet-extension>. The following list of elements are proposed metadata items that would be used inside of <facet-metadata>:

Item Name
Description / Use Case
deprecated A string providing a reason why the facet is deprecated. If there is a value, a tool might try to warn the user about the presence of the facet in his code.
expert A boolean to indicate whether this facet is for experts. Expert facets may be hidden in the UI unless the user requests them.
help-topic A string used to identify a help topic for the facet.
preferred A boolean indicating that the facet is likely to be created. Preferred facets may be featured more prominently.
preferred-child-components A space separated list of component types that are likely to be children of this component. Perhaps used for context-sensitive creation.
short-description A short description of the facet. Might be used in tooltips. A short-description typically differs from the standard description in that the short-description has been truncated.

Renderer Metadata and Grammar Information The <renderer> element inherently supports the following:
  • component-family
  • renderer-type
Combinations of component family and renderer type must be unique within the RenderKit associated with the parent "render-kit" element.

Renderers are unlike components, attributes, and facets in that a design-time tool does not want metadata about the renderer directly. Rather, the tool wants information about how a renderer affects a specific component. Therefore, the proposal is that an unlimited number of <component-metadata> elements could be used inside of <renderer-extension>, each of which would contain metadata overrides for a specific component type. Because renderers can define their own attributes, it is expected that sometimes components will need different metadata for different renderers. The syntax for overriding component metadata for a specific renderer will resemble the following:

<renderer>
   <!--set up the renderer here, declare any attributes, etc.-->
 
   <renderer-extension>
     <component-metadata component-type="command">
        <favorite-property>myRendererSpecificAttribute
        </favorite-property>
        <help-topic>myRendererSpecificHelpTopic</help-topic>
      </component-metadata>
   </renderer-extension>
</renderer>

b. Accessing Metadata when using JSP

The most common way to use JSF technology today is through JSP tag libraries, so it is worth discussing how a JSP-centric tool could access metadata stored in faces-config.xml. For a JSP-centric tool, the primary source of grammar information is the tag library. However, if the tag library is for JSF components, some important grammar information is missing (like what facets exist for a component). Given that the tag library does not contain all the necessary information, and that the proposal is to store metadata in faces-config.xml, it is clear that tools will need to pull information from both sources.

Given a JSP tag, however, how does a tool determine what portions of the faces-config.xml file are relevant? In order to map back from a JSP tag to the relevant portions of faces-config.xml, the tool will need to determine the component-type, renderer-type, and component-family. One strategy makes use of the expectation that most tag libraries for JSF components will be simple wrappers (and may even be automatically generated). In this strategy, the tool instantiates the tag class, checks to see if it extends the JSF base class UIComponentTag, and invokes the getComponentType() and getRendererType() methods. With the component-type, the tool can now locate the component and its metadata in the faces-config.xml file. In order to locate the renderer and the renderer-specific metadata, the tool must also know the component-family. A similar strategy of instantiating the UIComponent and calling getFamily() could be used, but a more performant solution is to look for the proposed <component-family> metadata in the <component-metadata> for the component. This is only one of many possible strategies for accessing faces-config.xml metadata given a JSP tag, and it is only presented here as an example.

III. Using Faces Metadata

The DTD for faces-config.xml defines the type for the various extension elements, such as <component-extension>, to be ANY. In the DTD language, ANY means that the element can contain zero or more child elements of any declared type, as well as character data. It is therefore a shorthand for mixed content containing all declared elements.

Because an element must be declared to be used, the internal document type definition of a faces-config.xml file must define all metadata items that it uses. This is one of many problems that arise because the faces-config.xml language is defined using a DTD. The hope is that JSF 1.2 will address this problem by replacing the DTD with an XML Schema. Until that change is made, in order to make a faces-config.xml file validate, one must declare any additional elements and attributes using a syntax like the following:

<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"
 [
 <!ELEMENT component-metadata ANY>
 <!ATTLIST component-metadata
     component-type CDATA #IMPLIED>
 <!ELEMENT facet-metadata ANY>
 <!ELEMENT attribute-metadata ANY>
 <!ELEMENT property-metadata ANY>
 <!ELEMENT accepts-child-components (#PCDATA)>
 <!ELEMENT attribute-values (#PCDATA)>
 <!ELEMENT base-component-type  (#PCDATA)>
 <!ELEMENT deprecated  (#PCDATA)>
 <!ELEMENT display-order  (#PCDATA)>
 <!ELEMENT expert  (#PCDATA)>
 <!ELEMENT favorite-property  (#PCDATA)>
 <!ELEMENT group  (#PCDATA)>
 <!ELEMENT help-topic  (#PCDATA)>
 <!ELEMENT hidden  (#PCDATA)>
 <!ELEMENT initial-value  (#PCDATA)>
 <!ELEMENT preferred  (#PCDATA)>
 <!ELEMENT preferred-child-tags  (#PCDATA)>
 <!ELEMENT property-editor  (#PCDATA)>
 <!ELEMENT short-description  (#PCDATA)>
 <!ELEMENT writable  (#PCDATA)>

]
>

a. Extending the Metadata Language

This proposal by no means defines all possible metadata for Faces components. While the goal is to define common metadata items that all tools support, tools must be able to extend the metadata language to add their own tool-specific metadata. As long as the grammar for faces-config.xml is defined by a DTD, the mechanism for extending the proposed metadata language is simple: just add element definitions into the internal document type definition. Unfortunately, different tools can easily use the same names for metadata that they interpret differently, so to avoid collisions consider prefixing all tool-specific metadata with the name of the tool. Once JSF uses an XML schema to define the grammar for faces-config.xml, metadata elements can be namespaced to avoid conflicts and a much more precise means of extending the metadata language can be defined via XML Schema's substitution group mechanism.

Many metadata items that currently must be tool-specific, such as wizards that are launched when an component is created, alternative renderers to use for a component at design-time, contextual action providers, and validators could be made part of the standard if the tool vendors agree upon a common API. The more metadata that can be standardized, the easier it will be for component authors to enable good design-time support in a variety of tools.

IV. Metadata in Action


Below is an example of how a tool might use metadata that lives in faces-config.xml.

Metadata in Action
Note the following:
  • Icons appear in the palette and structure pane.
  • Context sensitive insertion shows the preferred components.
  • Display names are used for tag libraries in the palette and context menu.
  • Attributes are grouped and ranked according to metadata in the property inspector.
  • The favorite property of graphicImage (url) is used to identify the graphicImage in the structure pane.
Metadata can be used throughout the tool to provide a polished design-time experience.

V. Conclusion

Now is the time for tools and component vendors to collaborate on a standard for providing design-time metadata for JSF components. JSF represents a great step forward in web application development, but success for the run-time platform depends in large part on tools support. Oracle hopes that this document initiates a discussion that will benefit the JSF community by making it easier for component authors to provide a good design-time experience for their components in a variety of tools.

Interested in discussing this proposal? Share your opinion in the official JSF forum


RSS feed(all feeds)

The Editor's Desk
Podcasts
Inside Facelets
In the Trenches

Site version 1.83  Report web site problems

Copyright (C) 2003-2014 Virtua, Inc. All Rights Reserved. Java, JavaServer Faces, and all Java-based marks are trademarks or registered trademarks of Oracle Corporation. in the United States and other countries. Virtua, Inc. is independent of Oracle Corporation. All other trademarks are the sole property of their respective owners.