Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

JSF Composite: Applying Reusability of code

See this article using the Composite JSF 2.0 to apply the concept of reusability in your application.

It is essential that any application works with the concept of code reusability, so you can have greater flexibility in the code and productivity in the delivery time of a project. It is true that using reusability in Java is very common, but how we do it in XHTML with JSF? How often should you have asked: "I have to create the same data list screen 30 times if I have 30 listings panels?" The answer is no, and in this article we will see how to apply the concept of code reusability using Composite Components with JSF 2.0.

Introduction to Composite Components with JSF 2.0

Since JSF 2.0 appeared, you can make use of this powerful tool known as "Composite Components" that aims to provide reusability of components.

To illustrate this point, imagine the following scenario where the use of such action is necessary: You have multiple screens that perform CRUD operations and in all of them you have the buttons "New, Save, Delete and Cancel." You'd be creating several commandButtons every time there was a need, in this case on all screens, but you can create custom component (Composite Component) which will make the function of your commandButton in a generic way. It was complicated to understand? Do not worry, we will illustrate later.

Let's start using the Composite. For this, you must declare the namespace early in the HTML tag, as in Listing 1.

Listing 1. Declaring the namespace of the Composite Component

<html xmlns="http://www.w3.org/1999/xhtml"   
        //...
        xmlns:composite="http://java.sun.com/jsf/composite">
  </html>

This is the way to declare the composite to your XHTML, equal to the "import" of Java. In the composite there are two short and important tags that are essential to its operation:

1 - Interface (composite:interface): This tag is used to declare all the attributes that can be passed to use in our composite component, that is, if you want to create an attribute called "componentName" every time your component is created anywhere in the application you must pass the attribute "componentName", something like:

See in Listing 2 an example of the tag interface using.

Listing 2. composite:interface

<composite:interface> 
	<composite:attribute name="createBeanPage" shortDescription="Page where will be redirected when create a new Bean. Eg 'maintain_credit_card'" /> 
	<composite:attribute name="managedBeanName" type="br.com.myproject.mb.BasicCrudMBNewImpl" required="true" shortDescription="ManagedBean Name of component" />
	<composite:attribute name="disabledLogic" default="#{cc.attrs.managedBeanName.bean == null}" shortDescription="Additional logic for the component be disabled. Ex: When the status of a subject is ACTIVE or INACTIVE" /> 
</composite:interface>

Let us understand the logic above our interface: we are creating attributes for later use, also to a method in Java, where it receives the parameters and you can use them wherever you want.

The "attribute" in the composite is the same as our parameter in Java. In the first case where we have the "createBeanPage", we are still putting a "shortDescription" which will serve to help to identify what it is for that attribute, what your actual need.

In the second case where we have the attribute "managedBeanName" and said that it shall be the type "BasicCrudMBNewImpl" and in the third case we passed a default value for our attribute when nothing is passed like attribute "disabledLogic".

So we have all our defined attributes and where we use them? Here comes the second item.

2 - Implementation (composite:implementation): The attributes defined in "Interface" will be used here, we can use them in as many components as we want. We can, for example, create a default search page based on composite, just working with attributes. Let's see the example in Listing 3.

Listing 3. composite:implementation

<composite:implementation> 
	<p:toolbar> 
		<p:toolbarGroup align="left"> 
			<p:button icon="ui-icon-plus" value="New" id="newButton" alt="Click to add a new record" outcome="#{cc.attrs.managedBeanName.redirectCriarBean(cc.attrs.createBeanPage)}" /> 
			
			<p:commandButton disabled="#{cc.attrs.disabledLogic}" id="commandButtonRemove" value="Remove" icon="ui-icon-trash" onclick="varConfirmRemove.show()" type="button" /> 
			
			<p:confirmDialog id="confirmRemove" message="Would you like to remove ?" showEffect="fade" hideEffect="fade" header="Remove" severity="alert" widgetVar="varConfirmRemove"> 
				<p:commandButton value="Yes" oncomplete="varConfirmRemove.hide()" actionListener="#{cc.attrs.managedBeanName.delete}" update="@form" /> 
				<p:commandButton value="No" onclick="varConfirmRemove.hide()" type="button" /> 
			</p:confirmDialog> 
			<p:separator /> 
			<composite:insertChildren /> 
		</p:toolbarGroup> 
	</p:toolbar> 
</composite:implementation>

To access our attributes via "implementation" just do "#{} cc.attrs.attrinutename" and use it anywhere we wish. In our example above we have a new button and a button to remove that can be used in any part of our application and if we decide tomorrow to change the button icon, just change in one place, in the composite.

So, see how was our final composite, already created with all necessary attributes (Listing 4).

Listing 4. Composite with buttons New and Remove

<!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:ui="http://java.sun.com/jsf/facelets" 
	xmlns:h="http://java.sun.com/jsf/html" 
	xmlns:f="http://java.sun.com/jsf/core" 
	xmlns:p="http://primefaces.org/ui"
	xmlns:composite="http://java.sun.com/jsf/composite">

	<composite:interface> 
		<composite:attribute name="createBeanPage" shortDescription="Page where will be redirected when create a new Bean. Eg 'maintain_credit_card'" /> 
		<composite:attribute name="managedBeanName" type="br.com.myproject.mb.BasicCrudMBNewImpl" required="true" shortDescription="ManagedBean Name of component" />
		<composite:attribute name="disabledLogic" default="#{cc.attrs.managedBeanName.bean == null}" shortDescription="Additional logic for the component be disabled. Ex: When the status of a subject is ACTIVE or INACTIVE" /> 
	</composite:interface>

	<composite:implementation> 
		<p:toolbar> 
			<p:toolbarGroup align="left"> 
				<p:button icon="ui-icon-plus" value="New" id="newButton" alt="Click to add a new record" outcome="#{cc.attrs.managedBeanName.redirectCriarBean(cc.attrs.createBeanPage)}" /> 
				
				<p:commandButton disabled="#{cc.attrs.disabledLogic}" id="commandButtonRemove" value="Remove" icon="ui-icon-trash" onclick="varConfirmRemove.show()" type="button" /> 
				
				<p:confirmDialog id="confirmRemove" message="Would you like to remove ?" showEffect="fade" hideEffect="fade" header="Remove" severity="alert" widgetVar="varConfirmRemove"> 
					<p:commandButton value="Yes" oncomplete="varConfirmRemove.hide()" actionListener="#{cc.attrs.managedBeanName.delete}" update="@form" /> 
					<p:commandButton value="No" onclick="varConfirmRemove.hide()" type="button" /> 
				</p:confirmDialog> 
				<p:separator /> 
				<composite:insertChildren /> 
			</p:toolbarGroup> 
		</p:toolbar> 
	</composite:implementation>
</html>

Now let's see how to use our Composite in the project as if it were one more component in our "range of components", here's the steps below:

  1. Let's call the example of the list above as "newAndRemove.xhtml" and put it into the directory "webapp/resources/MyApplication/". The directory "MyApplication" may have the name that you want, it will be used to call all their composites that are in it, something like: .
  2. Now in the XHTML page that you want to use your component you must add the following NameSpace: "xmlns:MyApplication="http://java.sun.com/jsf/composite/minhaaplicacao"
  3. Remember that the name "MyApplication" is exactly the directory that quoted in step 1, so now you simply use the components that are in that directory, which has the same name as the XHTML file. In our case we create the file "newAndRemove.xhtml", then we can reference it as follows:
<myapplication:newAndRemove managedBeanName="#{categoryFlowMB}" createBeanPage="maintain_category" />

Note that we called tag "MyApplication" and then assigned parameters to our component called 'newAndRemove'.

InsertChildren

You may have noticed in Listing 4 we put a line "" and probably you might have wondered what's the function of this line?

With InsertChildren we give even more power to our component, enabling that when using it can be added other components within it. We will explain better with an example using the DataTable Primefaces component.

We have a DataTable that is common to multiple pages of our application, so let's create a component that creates a dataTable and leaves a insertChildren so that columns can be added to it. We will not go into details of the composite code, as already explained in the previous sections. Notice in Listing 5.

Listing 5. Creating a composite for dataTable with insertChildren

<!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:ui="http://java.sun.com/jsf/facelets" 
	xmlns:h="http://java.sun.com/jsf/html" 
	xmlns:f="http://java.sun.com/jsf/core" 
	xmlns:p="http://primefaces.org/ui"
	xmlns:composite="http://java.sun.com/jsf/composite">

	<composite:interface> 
		<composite:attribute name="idDataTable" default="listingDataTable" shortDescription="DataTable ID. Used to reference other parts of the code" /> 
		<composite:attribute name="managedBeanName" type="br.com.myproject.mb.BasicCrudMBNewImpl" required="true" shortDescription="ManagedBean Name of component" /> 
	</composite:interface> 
	
	<composite:implementation> 
		<p:dataTable rowKey="#{bean.id}" var="bean" value="#{cc.attrs.managedBeanName.beans}" paginator="true" emptyMessage="No record found" rows="10" id="#{cc.attrs.idDataTable}" selection="#{cc.attrs.managedBeanName.bean}" selectionMode="single"> 
			<p:ajax event="rowSelect" update="@form" /> 
			<p:ajax event="rowUnselect" update="@form" /> 
			<composite:insertChildren /> 
		</p:dataTable>
	</composite:implementation>
</html>

Then we have the header and footer of our ready made dataTable, simply add the columns, which always change from screen to screen. Let's see how to do this in Listing 6.

Listing 6. Inserting columns in our composite

<myapplication:appDataTable managedBeanName="#{categoryMB}"> 
	<p:column headerText="Description" sortBy="#{bean.description}" filterBy="#{bean.description}" id="description" filterMatchMode="contains"> 
		<h:link outcome="#{categoryFluxoMB.redirectAlterBean('maintain_category',bean.id)}" value="#{bean.description}" /> 
	</p:column> 
	<p:column headerText="Type" sortBy="#{bean.type.description}" filterBy="#{bean.type.description}" filterMatchMode="contains" id="type"> 
		<h:outputText value="#{bean.type.description}" /> 
	</p:column> 
</myapplication:appDataTable>

Note that we open the component with the "", put the columns in and closed with "" is exactly here that the insertChildren does its work, in this context it represents our columns that are inside the dataTable. Note that the name of our component is "appDataTable" and this means that the file name is "appDataTable.xhtml" which is inside the "webapp/resources/MyApplication".

We can use 2, 3, 4, 5 or how many composites we want in an XHTML page, is like any other component but customized for our need. We will see in Listing 7 the junction of our appDataTable + newAndRemove, two components designed for different needs, but they belong to the same context.

Listing 7. Using the composite appDataTable and newAndRemove

<!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:ui="http://java.sun.com/jsf/facelets" 
	xmlns:h="http://java.sun.com/jsf/html" 
	xmlns:f="http://java.sun.com/jsf/core" 
	xmlns:p="http://primefaces.org/ui"
	xmlns:myapplication="http://java.sun.com/jsf/composite/myapplication">
		<h:head>
		</h:head>
    <h:body>
		<ui:composition template="/templates/template.xhtml"> 
			<ui:define name="content"> 
				<h:form id="formCategories"> 
					<myapplication:newAndRemove managedBeanName="#{categoryMB}" pageCriarBean="maintain_category" /> 
					<myapplication:appDataTable managedBeanName="#{categoryMB}"> 
						<p:column headerText="Description" sortBy="#{bean.description}" filterBy="#{bean.description}" id="description" filterMatchMode="contains"> 
							<h:link outcome="#{categoryMB.redirectAlterBean('maintain_category', bean.id)}" value="#{bean.description}" /> 
						</p:column> 
						<p:column headerText="Tipo" sortBy="#{bean.type.description}" filterBy="#{bean.type.description}" filterMatchMode="contains" id="type"> 
							<h:outputText value="#{bean.type.description}" /> 
						</p:column> 
					</myapplication:appDataTable> 
				</h:form> 
			</ui:define> 
		</ui:composition> 
	</h:body>
</html>

We showed examples of how to create composites based on components to be reused in various parts of our application, but we can go higher the level and create entire pages composites, for example, a default search page that uses any application, whether a search employee, partner, store, product, or any other entity, will have the same layout and logic based on our composite. Let's end with Listing 8 below with the example of a composite that is a registration page based composite.

Listing 8. Creating a registration page with composite

<!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:ui="http://java.sun.com/jsf/facelets" 
	xmlns:h="http://java.sun.com/jsf/html" 
	xmlns:f="http://java.sun.com/jsf/core">
		<composite:interface> 
			<composite:attribute name="nameLable" /> 
			<composite:attribute name="nameValue" /> 
			<composite:attribute name="emailLable" /> 
			<composite:attribute name="emailValue" /> 
			<composite:attribute name="registerButtonText" /> 
			<composite:attribute name="registerButtonAction" method-signature="java.lang.String action()" /> 
		</composite:interface> 
		
		<composite:implementation> 
			<h:form> 
				<h:message for="textPanel" style="color:red;" /> 
				<h:panelGrid columns="2" id="textPanel"> 
					#{cc.attrs.nameLable} 
					: <h:inputText id="name" value="#{cc.attrs.nameValue}" /> 
					
					#{cc.attrs.emailLable} : 
					<h:inputText id="email" value="#{cc.attrs.emailValue}" /> 
				</h:panelGrid> 
				
				<h:commandButton action="#{cc.attrs.registerButtonAction}" value="#{cc.attrs.registerButtonText}" /> 
			</h:form> 
		</composite:implementation>
</html>

Let's see how to use our page above (Listing 9).

Listing 9. Using our registration 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:ui="http://java.sun.com/jsf/facelets" 
	xmlns:h="http://java.sun.com/jsf/html" 
	xmlns:myapplication="http://java.sun.com/jsf/composite/myapplication" > 
	
	<h:body> 
		<myapplication:register 
			nameLable="Name" 
			nameValue="#{user.name}" 
			emailLable="E-mail" 
			emailValue="#{user.email}" 
			registerButtonText="Register" 
			registerButtonAction="#{user.registerAction}" /> 
	</h:body>
</html>

And as you may have noticed, the name of our composite is "register.xhtml".

Conclusion

Importantly, this article showed introductory questions about the composite, but which are essential to start working with it and that in fact are the most frequently used, now part of you creativity and logic required to create their own complex composites enough to support the reusability of your code.



Julio is a System analyst and enthusiast of Information Technology. He is currently a developer at iFactory Solutions company, working in the development of strategic systems, is also a JAVA instructor. He has knowledge and experi...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login