Integration between JavaServer Faces and Web Components
Java HTML
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src/main
web Refactor; turned this into a JAR project using Maven and started movi… Sep 21, 2016
.gitignore Initial check-in Sep 20, 2016
README.asc
bower.json
pom.xml

README.asc

webfaces

webfaces is a library that helps you build JavaServer Faces components using Web Components.

Background

JavaServer Faces (JSF) is the standard API for building Java web applications (part of the Java Enterprise Edition, or Java EE) specification. A key part of JSF applications is a sever-side user interface component model. JSF pages ("views") are built out of smaller UI components. For examples, see the PrimeFaces showcase.

Web Components are a set of relatively new HTML5 standards that bring a native component model to HTML, with a full-fledged JavaScript API. Since the standard is integrated into browsers, it allows you to build reusable components that work like ordinary HTML tags. Web Components aren’t tied to a specific JavaScript framework. For examples, see webcomponents.org.

JSF components often expose both a server-side Java API and a client-side JavaScript API. Usually the client-side APIs are built with proprietary frameworks and libraries such as a jQuery. However, Web Components are particularly well suited for for exposing the client-side API. Such components provide a more consistent, standard approach for client-side integration and are more likely to work with third-party JavaScript web frameworks.

For more information about how these two component models compare, see the presentation JavaServer Faces and HTML5 Web Components: Synergy? (presented at JavaOne and Devnexus).

Building

This is a very simple Maven project; once you have Maven installed, simply run mvn install from the project root folder. The output JAR file will be in the target folder

Getting Started

Once you have built the project, just copy the JAR file into the WEB-INF/lib folder of your JSF web app. This will give you access to a few special components which allow you to write a JSF composite component that renders as a web component:

resources/webfaces-demo/hello-world.xhtml
 <?xml version="1.0" encoding="UTF-8"?>
 <ui:composition xmlns:h="http://java.sun.com/jsf/html"
                 xmlns:ui="http://java.sun.com/jsf/facelets"
                 xmlns:cc="http://java.sun.com/jsf/composite"
                 xmlns:jsf="http://xmlns.jcp.org/jsf"
                 xmlns:wf="uri:webfaces">

     <cc:interface name="HelloWorld">
         <cc:attribute name="message" type="java.lang.String"/>
     </cc:interface>
     <cc:implementation>
         <wf:template id="hello-world-template" pass-through-attribute="blah">
             <style>
                 :host {
                     display: block;
                     border-style: solid;
                     border: 1px;
                 }
             </style>
             <div>
                 Hello world, <span id="message">#{cc.attrs.message}</span>.
             </div>
             <div>
                 You are using #{facesContext.externalContext.request.getHeader('User-Agent')}.
             </div>
         </wf:template>

         <hello-world class="test" id="#{cc.attrs.id}" message="#{cc.attrs.message}!"/>

         <wf:renderOnce group="webfaces-demo-hello-world">
             <h:outputScript id="hello-world-script">
                 class HelloWorld extends HTMLElement {

                     static get observedAttributes() {
                         return ['message'];
                     }

                     constructor() {
                         super();
                         let template = document.querySelector('#hello-world-template').content.cloneNode(true);
                         let root = this.attachShadow({mode: 'open'});
                         root.appendChild(template);
                     }

                     get message() {
                         return this.hasAttribute('message');
                     }

                     set message(message) {
                         if (message) {
                             this.setAttribute('message', message);
                         } else {
                             this.removeAttribute('message');
                         }
                     }

                     /** Fires when an instance was inserted into the document */
                     connectedCallback() {

                     };

                     /** Fires when an instance was removed from the document */
                     disconnectedCallback() {
                     };

                     /** Fires when an attribute was added, removed, or updated */
                     attributeChangedCallback(attr, oldVal, newVal) {
                         if (attr === 'message') {
                             let messageElement = this.shadowRoot.querySelector('#message');
                             messageElement.innerText = newVal;
                         }
                     }

                     /** Fires when the element is moved to a new document */
                     adoptedCallback() {
                     }
                 }
                 window.customElements.define('hello-world', HelloWorld);

             </h:outputScript>
         </wf:renderOnce>
     </cc:implementation>

 </ui:composition>

You can then use this in any JSF page like any other JSF component:

index.html
<?xml version="1.0" encoding="UTF-8"?>
<!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://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:demo="http://java.sun.com/jsf/composite/webfaces-demo">

<f:view transient="true"/>
<h:head>
    <script type="text/javascript" src="#{facesContext.externalContext.requestContextPath}/resources/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
</h:head>
<h:body>
    <demo:hello-world id="hello1" message="#{param.message}"/>
   <input id="messageInput" value="#{param.message}" onkeyup="updateComponents(this.value)"></input>
    <script type="text/javascript">
        function updateComponents(value) {
        	document.querySelector('#hello1').message = value;
        }
    </script>
</h:body>
</html>

The key here is the client-side API. Since hello-world is a web component, you can retreive it via the DOM like any other element, and it will have whichever additional properties and methods you have defined. This avoids the extra effort required to build custom scaffolding for client-side widgets; you can simply #UseThePlatform.

Sample Applications

There are two separate sample applications available which make use of this library. Take a look at these apps to see how to use the webfaces to build JSF components with Web Components APIs:

License

This software has been released under the MIT License:

Copyright 2016-2017 Virtua, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Brought to you by virtua.tech