| | 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.
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
|
|