JSF2 Composite Component Metadata - No Fluff Just Stuff

JSF2 Composite Component Metadata

Posted by: Ed Burns on September 2, 2009

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

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml"
  3.      xmlns:h="http://java.sun.com/jsf/html"
  4.      xmlns:f="http://java.sun.com/jsf/core"
  5.      xmlns:my="http://java.sun.com/jsf/composite/cc"
  6.      xmlns:meta="http://mojarra.dev.java.net/cc-metadata">
  7. <h:head>
  8.   <title>A Simple JavaServer Faces 2.0 View</title>
  9. <style type="text/css">
  10. .grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9;  }
  11.  
  12. </h:head>
  13. <h:body>
  14.   <h:form>
  15.  
  16.     <p>Composite Component usage:</p>
  17.  
  18. <div id="cc" class="grayBox" style="border: 1px solid #090;">
  19. <my:myComponent loginAction="#{userBean.loginAction}" />
  20. </div>
  21.  
  22. <h2>Metada for This Composite Component</h2>
  23.  
  24. <div id="foo" class="grayBox" style="border: 1px solid #090;">
  25.     <pre>
  26.     <meta:printMetadata viewName="main.xhtml" libraryName="cc"
  27.                        resourceName="myComponent.xhtml"/>
  28.     </pre>
  29. </div>
  30.  
  31.  
  32.     <p><h:commandButton value="submit" /></p>
  33.   </h:form>
  34. </h:body>
  35. </html>
  36.  

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

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml"
  3.      xmlns:h="http://java.sun.com/jsf/html"
  4.      xmlns:f="http://java.sun.com/jsf/core"
  5.      xmlns:ui="http://java.sun.com/jsf/facelets"
  6.      xmlns:fmd="http://java.sun.com/xml/ns/javaee/faces/design-time-metadata"
  7.      xmlns:cc="http://java.sun.com/jsf/composite">
  8.  
  9. <title>Not present in rendered output</title>
  10.  
  11. </head>
  12.  
  13.  
  14. <cc:interface
  15.    name="component"
  16.    displayName="A really fancy composite component"
  17.    expert="true"
  18.    hidden="false"
  19.    preferred="true"
  20.    shortDescription="This component has all the supported metadata."
  21.    extraTopLevelAttribute="Whatever I want here">
  22.  
  23. <!-- start top level attributes -->
  24.  
  25.   <cc:attribute
  26.    name="model"
  27.    required="true"
  28.    displayName="model"
  29.    expert="false"
  30.    hidden="false"
  31.    preferred="true"
  32.    shortDescription="The model for this component"
  33.    extraTopLevelAttribute="Whatever I want here">
  34.     <cc:extension>
  35.       <fmd:expert>true</fmd:expert>
  36.     </cc:extension>
  37.     <cc:attribute
  38.      name="userid"
  39.      default="guest"
  40.      displayName="User Id"
  41.      expert="false"
  42.      hidden="false"
  43.      preferred="true"
  44.      shortDescription="The model must have a userid property"/>
  45.     <cc:attribute
  46.      name="password"
  47.      default="guest"
  48.      displayName="Password"
  49.      expert="false"
  50.      hidden="false"
  51.      preferred="true"
  52.      shortDescription="The model must have a password property"/>
  53.   </cc:attribute>
  54.  
  55.   <cc:attribute name="useridLabel" default="Userid:" />
  56.  
  57.   <cc:attribute name="passwordLabel" default="Password:" />
  58.  
  59.   <cc:attribute name="loginButtonLabel" default="Login" />
  60.  
  61.   <cc:attribute name="loginAction" method-signature="java.lang.String f()"
  62.    required="true" />
  63.  
  64. <!-- end top level attributes -->
  65.  
  66. <!-- start facets -->
  67.  
  68.   <cc:facet
  69.    name="header"
  70.    displayName="The header facet for the fancy component"
  71.    expert="true"
  72.    hidden="false"
  73.    preferred="false"
  74.    shortDescription="If you want a header, this is where you put it"
  75.    anotherExtraAttribute="Lots of metadata" />
  76.  
  77.   <cc:facet
  78.    name="footer"
  79.    displayName="The footer facet for the fancy component"
  80.    expert="true"
  81.    hidden="false"
  82.    preferred="false"
  83.    shortDescription="If you want a footer, this is where you put it"
  84.    anotherExtraAttribute="Lots of metadata" />
  85.  
  86. <!-- end facets -->
  87.  
  88. <!-- start attached objects -->
  89.  
  90.   <cc:editableValueHolder
  91.    name="userid"
  92.    displayName="Userid field"
  93.    expert="true"
  94.    hidden="false"
  95.    preferred="false"
  96.    shortDescription="Attach a converter or validator here, if you like"
  97.    someExtraMetadata="userid metadata" />
  98.  
  99.   <cc:editableValueHolder
  100.    name="password"
  101.    displayName="Password field"
  102.    expert="true"
  103.    hidden="false"
  104.    preferred="false"
  105.    shortDescription="Attach a converter or validator here, if you like"
  106.    someExtraMetadata="password metadata" />
  107.  
  108.   <cc:actionSource
  109.    name="login"
  110.    displayName="Login button"
  111.    expert="true"
  112.    hidden="false"
  113.    preferred="false"
  114.    shortDescription="Attach an actionListener here, if you like"
  115.    someExtraMetadata="login metadata" />
  116.  
  117. <!-- end attached objects -->
  118.  
  119. </cc:interface>
  120.  
  121. <cc:implementation>
  122.  
  123.   <cc:renderFacet name="header" />
  124.  
  125.   <p><h:outputLabel for="#{cc.clientId}:userid"
  126.                    value="#{cc.attrs.useridLabel}" />
  127.      <h:inputText id="userid" /></p>
  128.  
  129.   <p><h:outputLabel for="#{cc.clientId}:password"
  130.                    value="#{cc.attrs.passwordLabel}" />
  131.      <h:inputText id="password" /></p>
  132.  
  133.   <p><h:commandButton value="#{cc.attrs.loginButtonLabel}"
  134.                      action="#{cc.attrs.loginAction}" /></p>
  135.  
  136.   <cc:renderFacet name="footer" />
  137.  
  138.  
  139. </cc:implementation>
  140.  
  141. </body>
  142.  
  143. </html>
  144.  

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

  1. <facelet-taglib  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  2.   xmlns='http://java.sun.com/xml/ns/javaee'
  3.   xsi:schemaLocation='http://java.sun.com/xml/ns/javaee web-facelettaglibrary_2_0.xsd'
  4.   version="2.0">
  5.     <namespace>http://mojarra.dev.java.net/cc-metadata</namespace>
  6.     <tag>
  7.         <tag-name>printMetadata</tag-name>
  8.         <component>
  9.             <component-type>jsf2.PrintMetadata</component-type>
  10.         </component>
  11. <!-- these are advisory and not enforced by the runtime -->
  12.         <attribute>
  13.             <name>viewName</name>
Ed Burns

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...
Learn More »