November 15, 2015

CrudFaces: JSF best practices out-of-the-box



Do you feel like every time you start a JSF project, you have to reinvent the wheel to realize the same CRUD operations again? Do you feel like you waste precious development time to build JSF / PrimeFaces hacks and workarounds rather than developing actual business logic? Then you should take a close look at CrudFaces.

The good parts

Use PrimeFaces with Bootstrap

Activate it with a single faces-config.xml config:
<factory>
    <render-kit-factory>
        ch.codebulb.crudfaces.renderkit.StyleClassChangeRenderKitFactory
    </render-kit-factory>
</factory>

A truly responsive, implicit grid form layout

<cf:formLayout groups="2" styleClass="clearfix" style="margin-bottom: 12px;">
    <p:outputLabel for="firstName" value="\#{I18N['firstName']}"/>
    <p:inputText id="firstName" value="\#{formLayoutController.entity.firstName}"/>
    <p:message for="firstName"/>
    <p:outputLabel for="lastName" value="\#{I18N['lastName']}"/>
    <p:inputText id="lastName" value="\#{formLayoutController.entity.lastName}"/>
    <p:message for="lastName"/>
    <p:commandButton value="\#{I18N['save']}" update="@form"/>
</cf:formLayout>

Un-hide a component without need for a parent component

<p:commandLink id="button" a:stealth="#{not stealthModeController.shown}" 
    class="btn btn-default">
    Destroy the world!
</p:commandLink>
<p:commandButton value="#{stealthModeController.controlText}"
    actionListener="#{stealthModeController.switchShown()}"
    process="@this" update="@this button"
/>

Make a request scoped backing bean flash scoped

<cf:formLayout>
    <p:outputLabel for="textFlash" value="@RequestScoped bean text:"/>
    <h:outputText id="textFlash" value="#{flashBeans.requestScopedBean.text}"/>
    <p:commandButton value="Update text and reload"
     action="#{flashBeans.requestScopedBean.updateText()}" ajax="false"/>
</cf:formLayout>

The best parts

Apart from the independently useful components presented above plus some additional components which come bundles with CrudFaces, the project mainly addresses building best-practices compliant CRUD (Create, Read, Update, Delete) applications. It does so by providing a bunch simple, lean Java base classes which you can derive from to build a CRUD application in about 30 lines of Java code:
@ViewScoped
@Named
public class CustomerController extends CrudTableController<Customer> {
    @Inject
    private CustomerService service;
    
    @Override
    protected CrudService<Customer> getService() {
        return service;
    }
}
public class CustomerService extends CrudService<Customer> {
    @Override
    @PersistenceContext
    protected void setEm(EntityManager em) {
        super.setEm(em);
    }

    @Override
    public Customer create() {
        return new Customer();
    }

    @Override
    public Class<Customer> getModelClass() {
        return Customer.class;
    }
}
Most importantly, they support building RESTful JSF applications based on PrimeFaces components like <p:dataTable>, ready for use with PrettyFaces.

CrudFaces is not a replacement for PrimeFaces nor OmniFaces. Instead, it builds on top of them in order to create a smooth, modern, robust tech stack.

With more still to come

Please take a look at the project’s GitHub page and the live showcase demo to see which functionality is currently provided.

CrudFaces 0.1 is now released. However, a lot of its functionality is in a very early stage, and some of its features really are barely more than proof of concepts or early beta versions. I hope to add more functionality to existing components, and I have lots of additional features planned to be added in future versions to make JSF development even more easier and enjoyable. I want this project to become the culmination of my experience from 5+ years of JSF development.

I hope that this project has awaken your interest. Please feel free to share your opinion, your thoughts or any questions in the comments section below.


No comments:

Post a Comment