Skip to content
Ig edited this page Jun 9, 2014 · 6 revisions

Goal

There is one and only one goal for this project - to make jsf developers more productive. That means you startup and develop JSF application easily.

Why you should use it

You will create a new project very fast and will get a lot of stuff out of box.

  • Project configured with JSF/Spring/Hibernate stack with newest versions and working out of box on Tomcat.
  • JSF composite components created that can be reused a lot. They of course can be modified to better fit your needs.
  • Spring-data and querydsl integration. Those are state of the art technologies to work with DB layer.
  • Basic unit tests. Also integration tests in spring container are added and you wont need to search internet about how to configure that.
  • Logging with log4j configured.
  • Maven.
  • Easy modifiable crud (see example) with lazy data table. And you don't need to sell your soul to some code generator which generates stupid code and you can't modify it. You will simply need to add jsf field component with field name and component recognize its type and does the rest.
  • Spring authentication configured.
  • Rest web services configured and ready to use.
  • Maven site configured with various plugins like pmd, findbugs, javadoc, cobertura etc.
  • This is archetype, so all the code belongs to project and can be easily changed/modified after project is created.

In short this archetype already contains a lot of stuff that real projects needs and developers spend a lot of time searching how to do that and working on configurations solving problems, fighting frameworks and not concentrating on business logic. I hope happyfaces archetype will allow you to work more on business requirements and less on configuring and integrating various frameworks!

Example

Here is small example how simple application looks like.

This is how the code looks like for this lazy datatable and search page.

<ui:define name="content">
	<hf:searchPanel columns="4" backingBean="#{accountBean}">
		<hf:searchField label="#{messages['account.accountNumber']}" field="accountNumber" />
		<hf:searchField label="#{messages['account.active']}" field="active" isMessage="true" />
		<hf:searchEntityField label="#{messages['account.customer']}" field="customer" childField="name" popup="true" />
		<hf:searchField label="#{messages['account.openingDate']}" field="openingDate" rangeSearch="false" />
	</hf:searchPanel>

	<hf:dataList label="#{messages['account.search.results']}" backingBean="#{accountBean}">
		<hf:column label="#{messages['account.accountNumber']}" field="accountNumber" />
			
		<hf:column label="#{messages['account.active']}" field="active" isMessage="true" />
		<hf:column label="#{messages['account.customer']}" field="customer" childField="name" entityView="/pages/customerEdit.xhtml" popupFields="email,phone,address" />
		<hf:column label="#{messages['account.openingDate']}" field="openingDate" isDate="true" />
		<hf:actionsColumn />
	</hf:dataList>
		
	<!-- Popup component -->
	<hf:entityPopup id="customersPopup" header="#{messages['customer.search']}" updateField=":searchForm:customer" selection="#{accountBean.filters['customer']}"
			backingBean="#{customerBean}" searchField1Label="#{messages['customer.name']}" searchField1="name" column1Label="#{messages['customer.name']}" column1="name" 
			column2Label="#{messages['customer.email']}" column2="email" />
			
</ui:define>

And this is account edit page example:

The code for form edit:

<ui:define name="content">
	
	<hf:formPanel label="#{messages['account.page.panel']}" backingBean="#{accountBean}" edit="#{edit}" >
			
		<hf:formField label="#{messages['account.accountNumber']}" field="accountNumber" required="true" />
		<hf:formField label="#{messages['account.active']}" field="active" isMessage="true" />
		<hf:formEntityField label="#{messages['account.customer']}" field="customer" childField="name" popup="true" />
		<hf:formField label="#{messages['account.operations']}" field="operations"
				showFields="operation.operationName,operationName;operation.amount,amount;operation.operationType,operationType,msg;" />
		
	</hf:formPanel>

	<hf:entityPopup id="customersPopup" header="#{messages['customer.search']}" updateField=":mainForm:customer" selection="#{accountBean.entity.customer}"
			backingBean="#{customerBean}" searchField1Label="#{messages['customer.name']}" searchField1="name" column1Label="#{messages['customer.name']}" column1="name" 
			column2Label="#{messages['customer.email']}" column2="email" />

</ui:define>

This is bean that handles both search, and form edit pages:

@ManagedBean(name = "accountBean")
@ViewScoped
public class AccountBean extends BaseBean<Account> {

    private static final long serialVersionUID = 1L;

    @ManagedProperty(value = "#{accountService}")
    private IAccountService accountService;

    public AccountBean() {
        super(Account.class);
    }

    @Override
    protected IService<Account> getPersistenceService() {
        return accountService;
    }

    public void setAccountService(IAccountService accountService) {
        this.accountService = accountService;
    }

}

Not that much code isn't it?

Where to get help and find out what is happening

http://groups.google.com/forum/?fromgroups#!forum/happyfacescrud

Clone this wiki locally