This ultra-quick blog entry shows how to use the JSF runtime to access metadata for a composite component. Note that most of the metadata is optional when creating a composite component, therefore, this entry will be of interest to tool vendors and those wishing to write composite components that stand a chance of showing up nicely in tools.
The Using Page
When showing a composite component demo, I always like to start out with the using page.
Listing 1: the using page
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:my="http://java.sun.com/jsf/composite/cc"
- xmlns:meta="http://mojarra.dev.java.net/cc-metadata">
- <h:head>
- <style type="text/css">
- .grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9; }
- </style>
- </h:head>
- <h:body>
- <h:form>
- <div id="cc" class="grayBox" style="border: 1px solid #090;">
- <my:myComponent loginAction="#{userBean.loginAction}" />
- </div>
- <div id="foo" class="grayBox" style="border: 1px solid #090;">
- <pre>
- <meta:printMetadata viewName="main.xhtml" libraryName="cc"
- resourceName="myComponent.xhtml"/>
- </pre>
- </div>
- </h:form>
- </h:body>
- </html>
Line 5 declares the namespace “my” using the handy
composite component namespace prefix
“http://java.sun.com/jsf/composite” followed by
“cc”. JSF 2 interprets this to mean: treat any .xhtml files
in the directory /resources/cc as a JSF composite
component.
Line 6 declares a Facelet custom tag library with the namespace “http://mojarra.dev.java.net/cc-metadata”.
Line 20 uses the composite component named “myComponent” in the “cc” library.
Line 27 uses the “printMetadata” component from the Facelet custom tag library. We must pass in the name of a Facelet page, the library name, and the resource name.
The Composite Component
Let's examine the composite component itself. As I mentioned earlier, most of this metadata is optional and is included here just to show what the system understands. This component has just about every kind of metadata that is in the JSF2 spec.
Listing 2 the composite component
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:h="http://java.sun.com/jsf/html"
- xmlns:f="http://java.sun.com/jsf/core"
- xmlns:ui="http://java.sun.com/jsf/facelets"
- xmlns:fmd="http://java.sun.com/xml/ns/javaee/faces/design-time-metadata"
- xmlns:cc="http://java.sun.com/jsf/composite">
- <head>
- </head>
- <body>
- <cc:interface
- name="component"
- displayName="A really fancy composite component"
- expert="true"
- hidden="false"
- preferred="true"
- shortDescription="This component has all the supported metadata."
- extraTopLevelAttribute="Whatever I want here">
- <!-- start top level attributes -->
- <cc:attribute
- name="model"
- required="true"
- displayName="model"
- expert="false"
- hidden="false"
- preferred="true"
- shortDescription="The model for this component"
- extraTopLevelAttribute="Whatever I want here">
- <cc:extension>
- <fmd:expert>true</fmd:expert>
- </cc:extension>
- <cc:attribute
- name="userid"
- default="guest"
- displayName="User Id"
- expert="false"
- hidden="false"
- preferred="true"
- shortDescription="The model must have a userid property"/>
- <cc:attribute
- name="password"
- default="guest"
- displayName="Password"
- expert="false"
- hidden="false"
- preferred="true"
- shortDescription="The model must have a password property"/>
- </cc:attribute>
- <cc:attribute name="useridLabel" default="Userid:" />
- <cc:attribute name="passwordLabel" default="Password:" />
- <cc:attribute name="loginButtonLabel" default="Login" />
- <cc:attribute name="loginAction" method-signature="java.lang.String f()"
- required="true" />
- <!-- end top level attributes -->
- <!-- start facets -->
- <cc:facet
- name="header"
- displayName="The header facet for the fancy component"
- expert="true"
- hidden="false"
- preferred="false"
- shortDescription="If you want a header, this is where you put it"
- anotherExtraAttribute="Lots of metadata" />
- <cc:facet
- name="footer"
- displayName="The footer facet for the fancy component"
- expert="true"
- hidden="false"
- preferred="false"
- shortDescription="If you want a footer, this is where you put it"
- anotherExtraAttribute="Lots of metadata" />
- <!-- end facets -->
- <!-- start attached objects -->
- <cc:editableValueHolder
- name="userid"
- displayName="Userid field"
- expert="true"
- hidden="false"
- preferred="false"
- shortDescription="Attach a converter or validator here, if you like"
- someExtraMetadata="userid metadata" />
- <cc:editableValueHolder
- name="password"
- displayName="Password field"
- expert="true"
- hidden="false"
- preferred="false"
- shortDescription="Attach a converter or validator here, if you like"
- someExtraMetadata="password metadata" />
- <cc:actionSource
- name="login"
- displayName="Login button"
- expert="true"
- hidden="false"
- preferred="false"
- shortDescription="Attach an actionListener here, if you like"
- someExtraMetadata="login metadata" />
- <!-- end attached objects -->
- </cc:interface>
- <cc:implementation>
- <cc:renderFacet name="header" />
- <p><h:outputLabel for="#{cc.clientId}:userid"
- value="#{cc.attrs.useridLabel}" />
- <h:inputText id="userid" /></p>
- <p><h:outputLabel for="#{cc.clientId}:password"
- value="#{cc.attrs.passwordLabel}" />
- <h:inputText id="password" /></p>
- <p><h:commandButton value="#{cc.attrs.loginButtonLabel}"
- action="#{cc.attrs.loginAction}" /></p>
- <cc:renderFacet name="footer" />
- </cc:implementation>
- </body>
- </html>
Lines 16 - 23 declare the top level composite component metadata.
Lines 25 - 65 declare the attributes that may be passed as XML
elements on the composite component instance in the using page. Note
that the loginAction attribute is declared as required on
line 63. This is useful because Facelets will put up a helpful error if
the page author doesn't supply a value here.
Lines 68 - 88 declare the allowable facets. In this case, they're optional.
Lines 90 - 119 declare the attached objects within the implementation section that are publically accessible from the using page.
Programmatically accessing the metadata
Up to this point, everything I've shown has been included in other
blog entries elsewhere. What hasn't been shown is how the JSF runtime
uses the metadata API to actually conjure up the composite component
instance. This API is also accessible to tools that want to embed a JSF
runtime into their tool environment. To show this off, I've created a
non-composite JSF component and exposed it in the usual way, with a
Facelet taglib. This still requires a descriptor, which is placed in
WEB-INF/classes/META-INF.
Listing 3 the cc-metadata.taglib.xml
- <facelet-taglib xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
- xmlns='http://java.sun.com/xml/ns/javaee'
- xsi:schemaLocation='http://java.sun.com/xml/ns/javaee web-facelettaglibrary_2_0.xsd'
- version="2.0">
- <namespace>http://mojarra.dev.java.net/cc-metadata</namespace>
- <tag>
- <tag-name>printMetadata</tag-name>
- <component>
- <component-type>jsf2.PrintMetadata</component-type>
- </component>
- <!-- these are advisory and not enforced by the runtime -->
- <attribute>
- <name>viewName</name>
- Ed Burns's complete blog can be found at: http://weblogs.java.net/blog/edburns/
About Ed Burns
Ed Burns is currently a Senior Staff Engineer at Sun Microsystems, Inc. At Sun, Ed leads a team of web experts from across the industry in developing JavaServer™ Faces Technology through the Java Community Process and in open source. His areas of professional interests include web application frameworks, AJAX, reducing complexity, test driven development, requirements gathering, and computer supported collaborative work. Before working on JavaServer Faces, Ed worked on a wide variety of client and server side web technologies since 1994, including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat, the Cosmo Create HTML authoring tool, and the web transport layer in the Irix operating system from Silicon Graphics.
Ed has a Bachelor of Computer Science degree from the University of Illinois at Urbana Champaign. While at UIUC, Ed took a minor in Germanic Studies and worked for IBM in the co-op program, where he first aquired a fondness for computer history by working on System 370 Office Software.
Ed has presented many times at Sun's JavaOne conference, given a keynote address at the W-JAX conference in Munich, Germany, and also has spoken at numerous Java User Group meetings. Further information and blogs may be found at http://purl.oclc.org/NET/edburns/.
Why Attend the NFJS Tour?
- » Cutting-Edge Technologies
- » Agile Practices
- » Peer Exchange
Current Topics:
- Languages on the JVM: Scala, Groovy, Clojure
- Enterprise Java
- Core Java, Java 8
- Agility
- Testing: Geb, Spock, Easyb
- REST
- NoSQL: MongoDB, Cassandra
- Hadoop
- Spring 4
- Cloud
- Automation Tools: Gradle, Git, Jenkins, Sonar
- HTML5, CSS3, AngularJS, jQuery, Usability
- Mobile Apps - iPhone and Android
- More...