Dependency Injection in JSF and ‘new’ is a dirty word
I am going to write some explanation that I have learned from training and discussed with my cohort. Please go get a cup of coffee before you start this journey. Yes, using ‘new’ is a dirty word in a sense that in this example, you wont see using ‘new’ to instantiate an object instead use the injection capability in the faces-config.xml file. Please read these articles before proceed. Spring into JavaServer Faces and JSF-Spring
1. What does this following code mean?
<managed-bean> <managed-bean-name>applicantEditor</managed-bean-name> <managed-bean-class>training.jobapplication.bean.backing.ApplicantEditor</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
It means to create an instance of ApplicantEditor.java and make it available in request scope.
ApplicantEditor applicantEditor = new ApplicantEditor();
Here the ApplicantEditor.java looks like.
public class ApplicantEditor {
private boolean formRendered = false;
public boolean isFormRendered() {
return formRendered;
}
public void setFormRendered(boolean formRendered) {
this.formRendered = formRendered;
}
}
2. Let me explain these following code snippets
<managed-bean>
<managed-bean-name>applicantList</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.backing.ApplicantList</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>applicantEditor</property-name>
<value>#{applicantEditor}</value>
</managed-property>
<managed-property>
<property-name>applicantListModel</property-name>
<value>#{applicantListModel}</value>
</managed-property>
</managed-bean>
First of all, an instance has been created for ApplicantList in a request scope. Now, by looking at the line 6, I can tell that ApplicantList.java has a property/instance variable name applicantEditor <property-name> (it is a type of ApplicantEditor.java). Line 7, it’s calling setApplicantEditor() to set the value <#value>. Also same things are happening in line 10 and 11 for applicantListModel. Declare the property name using this tag <property-name>, and set the value by using this value tag <value> . ApplicantList contains a ‘has-a’ relationship of ApplicantEditor type. Easy, piece of cake and here is the proof:
package training.jobapplication.bean.backing;
import training.jobapplication.bean.model.ApplicantListModel;
import training.jobapplication.transfer.Applicant;
import javax.faces.component.UICommand;
import javax.faces.event.ActionEvent;
public class ApplicantList {
private ApplicantForm applicantForm;
private ApplicantEditor applicantEditor;
private ApplicantListModel applicantListModel;
public ApplicantForm getApplicantForm() {
return applicantForm;
}
public void setApplicantForm(ApplicantForm applicantForm) {
this.applicantForm = applicantForm;
}
public ApplicantListModel getApplicantListModel() {
return applicantListModel;
}
public void setApplicantListModel(ApplicantListModel applicantListModel) {
this.applicantListModel = applicantListModel;
}
public void checkAll(ActionEvent actionEvent) {
getApplicantListModel().checkAll();
}
public void create(ActionEvent actionEvent) {
getApplicantListModel().setSelectedAsNew();
getApplicantEditor().setFormRendered(true);
}
public void deleteChecked(ActionEvent actionEvent) {
getApplicantListModel().deleteChecked();
}
public void edit(ActionEvent actionEvent) {
UICommand uiCommand = (UICommand)actionEvent.getComponent();
Applicant applicant = (Applicant)uiCommand.getValue();
getApplicantListModel().setSelected(applicant);
getApplicantEditor().setFormRendered(true);
}
public void uncheckAll(ActionEvent actionEvent) {
getApplicantListModel().uncheckAll();
}
public ApplicantEditor getApplicantEditor() {
return applicantEditor;
}
public void setApplicantEditor(ApplicantEditor applicantEditor) {
this.applicantEditor = applicantEditor;
}
}
3. These snippets are the most confusing to me:
<managed-bean>
<managed-bean-name>applicantListModel</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.model.ApplicantLazyListModel</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>applicantService</property-name>
<value>#{applicantService}</value>
</managed-property>
<managed-property>
<property-name>rowsPerPage</property-name>
<value>#{userPreferences.rowsPerPage}</value>
</managed-property>
</managed-bean>
I try my best to explain. First of all, here’re some basic java polymorphism code.
Car car = new BMW(); car.go(); --> it calls BMW go() method super.go() --> it calls Car go() method.
We have to use our polymorphic power to understand this part. This is what’s happening in line 2 and 3 in above xml.
ApplicantListModel applicantListModel = new ApplicantLazyListModel(); or, ListModel applicantListModel = new ApplicantLazyListModel(); or, ApplicantLazyListModel applicantListModel = new ApplicantLazyListModel();
We dont know what ApplicantLazyListModel will rertun in run time. You may have noticed that applicantListModel is not the exact same object type as ApplicantLazyListModel.java but ApplicantLazyListModel.java extends ApplicantListModel.java. So there is an ‘is-a’ relationship going on. But Line 6, there is no guarantee that applicantService will be an instance variable (property) of ApplicantLazyListModel.java. Since ApplicantLazyListModel extends ApplicantListModel, we assume applicantService is a member of ApplicantListModel.java not ApplicantLazyListModel.
Okay, got that, if you dont just pretend you do, it will get clear after you see these following code. Now, here is the another fun part.
<managed-property>
<property-name>rowsPerPage</property-name>
<value>#{userPreferences.rowsPerPage}</value>
</managed-property>
I cant not find the property, rowsPerPage nor in ApplicantLazyListModel or ApplicantListModel, where it can be? ApplicantListModel also extends ListModel. So, rowPerPage is a member of ListModel.java. rowPerPage is also a proerty of UserPreferences.java. In the above xml, I’d read like this. rowPerPage is a property of applicantListModel which value has been set by calling get method, userPreferences.rowPerPage. Objects hierarchies are as follows.
public class ApplicantLazyListModel extends ApplicantListModel {
.....
}
public class ApplicantListModel extends ListModel {
private ApplicantService applicantService;
...
}
public abstract class ListModel {
private int rowsPerPage = -1;
...
}
package training.jobapplication.bean.util;
public class UserPreferences {
private int rowsPerPage = 5;
private int maxPageNumberNavControls = 3;
private boolean pageNumberNavControlsShown = true;
public int getRowsPerPage() {
return rowsPerPage;
}
public void setRowsPerPage(int rowsPerPage) {
this.rowsPerPage = rowsPerPage;
}
public int getMaxPageNumberNavControls() {
return maxPageNumberNavControls;
}
public void setMaxPageNumberNavControls(int maxPageNumberNavControls) {
this.maxPageNumberNavControls = maxPageNumberNavControls;
}
public boolean isPageNumberNavControlsShown() {
return pageNumberNavControlsShown;
}
public void setPageNumberNavControlsShown(boolean pageNumberNavControlsShown) {
this.pageNumberNavControlsShown = pageNumberNavControlsShown;
}
}
Man, now my brain hurts to think all these object relations. Feel free to write comments and more details in concept wise, visit my cohort David Wilson-Burns blog. He explains why we need Injection instantiation vs. using ‘new’ to create an object reference in Java. Here is the full faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<application>
<message-bundle>JSF-override</message-bundle>
<view-handler>com.icesoft.faces.facelets.D2DFaceletViewHandler</view-handler>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
<!--
<lifecycle>
<phase-listener>training.jobapplication.lifecycle.LoggingPhaseListener</phase-listener> </lifecycle>
-->
<converter>
<converter-id> provinceIdConverter </converter-id>
<converter-class> training.jobapplication.converter.ProvinceIdConverter </converter-class>
</converter>
<managed-bean>
<managed-bean-name>applicantEditor</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.backing.ApplicantEditor</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>applicantList</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.backing.ApplicantList</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>applicantEditor</property-name>
<value>#{applicantEditor}</value>
</managed-property>
<managed-property>
<property-name>applicantListModel</property-name>
<value>#{applicantListModel}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>applicantForm</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.backing.ApplicantForm</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>applicantEditor</property-name>
<value>#{applicantEditor}</value>
</managed-property>
<managed-property>
<property-name>applicantListModel</property-name>
<value>#{applicantListModel}</value>
</managed-property>
<managed-property>
<property-name>citySupport</property-name>
<value>#{citySupport}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>provinceSupport</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.support.ProvinceSupport</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>provinceService</property-name>
<value>#{provinceService}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>citySupport</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.support.CitySupport</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>cityService</property-name>
<value>#{cityService}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>applicantListModel</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.model.ApplicantLazyListModel</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>applicantService</property-name>
<value>#{applicantService}</value>
</managed-property>
<managed-property>
<property-name>rowsPerPage</property-name>
<value>#{userPreferences.rowsPerPage}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>userPreferences</managed-bean-name>
<managed-bean-class>training.jobapplication.bean.util.UserPreferences</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/applicantList.xhtml</from-view-id>
<navigation-case>
<to-view-id>/applicantForm.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/applicantForm.xhtml</from-view-id>
<navigation-case>
<to-view-id>/applicantList.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
Related Topics: What is Dependency Injection (DI) / Inversion of Control (IoC): “Hollywood Principle”—”don’t call us, we will call you”. – Wiki’s definition
Pros: The dependency injection approach offers more flexibility because it becomes easier to create alternative implementations of a given service type, and then to specify which implementation is to be used via a configuration file, without any change to the objects that use the service. This is especially useful in unit testing, because it is easy to inject a mock implementation of a service into the object being tested.
Cons: The price paid for that additional flexibility is greatly increased complexity and the fact that the program is no longer deterministic: it’s no longer possible to tell what functions will be called just by looking at the code.
Oracle Driver and Maven Repository
Why it is so hard to find a Oracle Driver in a Maven Reposity?
I don’t know the answer. I have looked up so many places but apparently only one repository so far I found has the latest jar. A “remote repository” that has the artifacts you are looking for. By default Maven uses the iBiblio repository but a lot of projects create and maintain their own repositories.

Here is the pom.xml. pom.xml
Sorry, I had to make my pom.xml to JPEG. Some reason WordPress was giving me Javascript error b/c of all different kind of tags the pom has.

Thanks to Jason Lee for his support and being my mentor in JEE world. Appreciated your help as always …..
For local jar file or project dependency, I have used <distributionManagement> tag. It’s very handy. This tag has to reside outside of <repositories> tag. So intead of http:// url, I have used windows file system path for repository references.
<distributionManagement> <repository> <id>Local Windows Repository</id> <url>file://C:\WorkspaceMyEclipse\HRTrainingPersistence\target\</url> </repository> </distributionManagement>
Click here to see the whole Maven pom file.
JavaScript in Facelets/XHTML
XHTML is more uniformed then regular html so here are few ways to add javascript code in a xhtml file
No. 1: Regular old style with special wrap (CDATA). Here is template.xhtml

No.2: External .js file
Create a .js file, like external.js
function externalJs(){
alert('external js file');
}
Now, add this <script type=”text/javascript” src=”external.js”></script> in the template.xhtml
Both of these java script call should work, one will come from template.xhmtl and other one will come from External JS file.
<f:view xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ice="http://www.icesoft.com/icefaces/component"> <ui:composition template="layout.xhtml"> <ui:define name="content"> <ice:form style="width: 45%;"> <a href="javascript: clicked();">JS in template.xhtml</a> <a href="javascript: externalJs();">External JS</a> </ice:form> </ui:define> </ui:composition> </f:view>
Related topics:
Five Steps to add Facelets
-
Archives
- November 2009 (1)
- July 2009 (1)
- June 2009 (5)
- May 2009 (2)
- April 2009 (4)
- March 2009 (2)
- January 2009 (3)
- December 2008 (1)
- November 2008 (2)
- October 2008 (1)
- September 2008 (3)
- August 2008 (2)
-
Categories
-
RSS
Entries RSS
Comments RSS
