A Generic Superclass for Sorting and Paginating in the database with Richfaces

In my previous post, I presented a solution for sorting and paginating in the database with Richfaces, and that post should be read prior to this one.  However, an examination of the previous solution shows that the only things that are specific to the items being presented are the Id of the item, the item itself, and the DAO used to perform the actual queries.  If we put all the parts of the code that deal with these three items into separate methods, and then override those methods in the subclasses, we can avoid duplicating code.  In contrast to my previous post, I will post all the code of the superclass up front, and then discuss it.  Generics are used so that the superclass can be provided with the types of the items and the id.

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;

import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;
import org.ajax4jsf.model.SerializableDataModel;

/**
 * @param 
 * @param <U>
 */
public abstract class PaginatingDataModel extends SerializableDataModel {
    /** */
    private static final long serialVersionUID = 2954923950179861809L;
    /** */
    protected U currentPk;
    /** */
    protected boolean descending = true;
    /** */
    protected String sortField = getDefaultSortField();
    /** */
    protected boolean detached = false;
    /** */
    protected List<U> wrappedKeys = new ArrayList<U>();
    /** */
    protected Integer rowCount;
    /** */
    protected Map<U> wrappedData = new HashMap<U>();

    /**
     * @see org.ajax4jsf.model.ExtendedDataModel#getRowKey()
     */
    @Override
    public Object getRowKey()
    {
        return currentPk;
    }

    /**
     * @see org.ajax4jsf.model.ExtendedDataModel#setRowKey(java.lang.Object)
     */
    @SuppressWarnings("unchecked")
    @Override
    public void setRowKey(final Object key)
    {
        this.currentPk = (U) key;
    }

    /**
     * @see org.ajax4jsf.model.SerializableDataModel#update()
     */
    @Override
    public void update()
    {
        if (getSortFieldObject() != null)
        {
            final String newSortField = getSortFieldObject().toString();
            if (newSortField.equals(sortField))
            {
                descending = !descending;
            }
            sortField = newSortField;
        }
        detached = false;
    }

    /**
     * @return Object
     */
    protected Object getSortFieldObject()
    {
        final FacesContext context = FacesContext.getCurrentInstance();
        final Object sortFieldObject = context.getExternalContext().getRequestParameterMap().get("sortField");
        return sortFieldObject;
    }

    /**
     * @param sortField
     */
    public void setSortField(final String sortField)
    {
        if (this.sortField.equals(sortField))
        {
            descending = !descending;
        } else
        {
            this.sortField = sortField;
        }
    }

    /**
     * @return String
     */
    public String getSortField()
    {
        return sortField;
    }

    /**
     * @see org.ajax4jsf.model.ExtendedDataModel#getSerializableModel(org.ajax4jsf.model.Range)
     */
    @Override
    public SerializableDataModel getSerializableModel(final Range range)
    {
        if (wrappedKeys != null)
        {
            detached = true;
            return this;
        }
        return null;
    }

    /**
     * @see javax.faces.model.DataModel#setRowIndex(int)
     */
    @Override
    public void setRowIndex(final int rowIndex)
    {
        throw new UnsupportedOperationException();

    }

    /**
     * @see javax.faces.model.DataModel#setWrappedData(java.lang.Object)
     */
    @Override
    public void setWrappedData(final Object data)
    {
        throw new UnsupportedOperationException();

    }

    /**
     * @see javax.faces.model.DataModel#getRowIndex()
     */
    @Override
    public int getRowIndex()
    {
        throw new UnsupportedOperationException();
    }

    /**
     * @see javax.faces.model.DataModel#getWrappedData()
     */
    @Override
    public Object getWrappedData()
    {
        throw new UnsupportedOperationException();
    }

    /**
     * @see org.ajax4jsf.model.ExtendedDataModel#walk(javax.faces.context.FacesContext,
     *      org.ajax4jsf.model.DataVisitor, org.ajax4jsf.model.Range,
     *      java.lang.Object)
     */
    @Override
    public void walk(final FacesContext context, final DataVisitor visitor, final Range range, final Object argument)
            throws IOException
    {
        final int firstRow = ((SequenceRange) range).getFirstRow();
        final int numberOfRows = ((SequenceRange) range).getRows();
        if (detached &amp;amp;&amp;amp; getSortFieldObject() != null)
        {
            for (final U key : wrappedKeys)
            {
                setRowKey(key);
                visitor.process(context, key, argument);
            }
        } else
        { // if not serialized, than we request data from data
            // provider
            wrappedKeys = new ArrayList<U>();
            for (final T object : findObjects(firstRow, numberOfRows, sortField, descending))
            {
                wrappedKeys.add(getId(object));
                wrappedData.put(getId(object), object);
                visitor.process(context, getId(object), argument);
            }
        }
    }

    /**
     * @see javax.faces.model.DataModel#isRowAvailable()
     */
    @Override
    public boolean isRowAvailable()
    {
        if (currentPk == null)
        {
            return false;
        }
        if (wrappedKeys.contains(currentPk))
        {
            return true;
        }
        if (wrappedData.entrySet().contains(currentPk))
        {
            return true;
        }
        try
        {
            if (getObjectById(currentPk) != null)
            {
                return true;
            }
        } catch (final Exception e)
        {

        }
        return false;
    }

    /**
     * @see javax.faces.model.DataModel#getRowData()
     */
    @Override
    public Object getRowData()
    {
        if (currentPk == null)
        {
            return null;
        }

        T object = wrappedData.get(currentPk);
        if (object == null)
        {
            object = getObjectById(currentPk);
            wrappedData.put(currentPk, object);
        }
        return object;
    }

    /**
     * @see javax.faces.model.DataModel#getRowCount()
     */
    @Override
    public int getRowCount()
    {
        if (rowCount == null)
        {
            rowCount = getNumRecords();
        }
        return rowCount;
    }

    /**
     * 
     * @param object
     * @return U
     */
    public abstract U getId(T object);

    /**
     * @param firstRow
     * @param numberOfRows
     * @param sortField
     * @param descending
     * @return List
     */
    public abstract List findObjects(int firstRow, int numberOfRows, String sortField, boolean descending);

    /**
     * @param id
     * @return T
     */
    public abstract T getObjectById(U id);

    /**
     * @return String
     */
    public abstract String getDefaultSortField();

    /**
     * @return int
     */
    public abstract int getNumRecords();
}


The abstract methods are all at the end.  Here is one possible subclass.  Note that it is Session scoped:


import static org.jboss.seam.ScopeType.SESSION;

import java.util.List;

import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;

import PaginatingDataModel;
import IFormsService;
import EntityDTO;
import FolderDTO;

@Name("newhireDataModel")
@Scope(SESSION)
public class NewhireList
    extends PaginatingDataModel
{
    /** */
    private static final long serialVersionUID = 2672142810059859813L;
    
    /** */
    @In
    private IFormsService serviceForms;
    
    /** */
    @In
    EntityDTO currentEntity;
    
    /** */
    @Logger
    Log log;
    
    /**
     * @see PaginatingDataModel#getId(java.lang.Object)
     */
    @Override
    public Integer getId(FolderDTO object)
    {
        return object.getPk();
    }
    
    /**
     * @see PaginatingDataModel#findObjects(int, int, java.lang.String, boolean)
     */
    @Override
    public List findObjects(int firstRow, int numberOfRows, String sortField, boolean descending)
    {
        return serviceForms.findFolders(firstRow, numberOfRows, sortField, descending);
    }
    
    /**
     * @see PaginatingDataModel#getObjectById(java.lang.Object)
     */
    @Override
    public FolderDTO getObjectById(Integer id)
    {
        return serviceForms.getFolder(id);
    }
    
    /**
     * @see PaginatingDataModel#getDefaultSortField()
     */
    @Override
    public String getDefaultSortField()
    {
        return "attribute(EOD)";
    }
    
    /**
     * @see PaginatingDataModel#getNumRecords()
     */
    @Override
    public int getNumRecords()
    {
        return serviceForms.countFolders(null, currentEntity);
    }
    
}

No change needs to be done to the JSF layer when using this solution.

Struts, Acegi, and JBoss Portal

You can easily find documentation for running struts applications as a JSR 168 portlet–for example, here. In fact, the JBoss Portal itself now ships with the apache portals-bridges-common library, so all you need to do is ship your application with the appropriate implementation from apache (in my case, portals-bridges-struts-1.2.7-1.0), and you can simply follow the standard instructions for getting any struts application running as a JSR 168 portlet. Those instructions say that you need a container specific implementation of org.apache.portals.bridges.common.ServletContextProvider, and fortunately, JBoss Portal ships with one–specifically, org.jboss.portal.portlet.bridge.JBossServletContextProvider, which the struts bridge expects you to declare in portlet.xml.

You can also find documentation for running applications requiring Acegi on the JBoss Portal. In fact, Acegi ships with a JBoss adaptor. This adaptor is in two parts–one that provides a JBoss Portal Login Module, and one that provides a filter that is meant to be used in place of the httpSessionContextIntegrationFilter. The Login Module returns an instance of Authentication, which JBoss Portal then makes available to all portlets via JNDI…specifically, it places a JAAS Subject at java:comp/env/security/Subject, and one of the principals associated with that subject will be the Authentication instance returned from the Login Module. It also makes the Principal available from the portletRequest object…just call portletRequest.getUserPrincipal(). If you look at the code of the filter, you can see that all it does is get the Subject from the jndi location, and then iterate through all of the associated JAAS Principals, looking for a Principal that is an instance of Authentication. It then places this Authentication in the SecureContext. Note that if you don’t have Acegi handle the login on the portal side of things, you won’t actually get a Principal that is an instance of Authentication, but in theory you can write your own filter which gets the active principal, calls getName() on the principal, (which returns the login name) and then looks up an Authentication instance in your database that corresponds to the name.

However, if you try to combine these two concepts–the Struts Bridge, and the filter, you will find that it doesn’t actually work. The issue is that when the acegi filter is running inside the struts bridge, there won’t actually be a subject at java:comp/env/security/Subject. If you cast the ServletRequest in the filter to an HttpServletRequest, and then call getUserPrincipal(), you won’t find anything there either. Oddly enough, if you put a scriptlet on the page that you want to display to the user, you will find that you can now access the Subject in JNDI, but by then it’s too late…you want the Authentication object in the SecureContext before the Acegi intercepting filter is run, not when you are displaying the page.

The solution is as follows: subclass the included JBossServletContextProvider, and then override the HttpServletRequest getHttpServletRequest(GenericPortlet genericPortlet, PortletRequest portletRequest) method. You’ll still want to get the HttpServletRequest to return, by calling super, but while you’re in this method, you have access to the Subject via JNDI, or, if you want, the Principal via portletRequest.getUserPrincipal. Once you have the Authentication instance, you have a couple of possibilities: You can place it in the session, and it will be available to you in an Acegi filter, where you can place it into the SecureContext. Alternatively, you can place it directly into the SecureContext. Note that placing it into the request won’t help…it won’t be available to you in the request object in the Acegi filter. If you use this method, don’t forget to update portlet.xml and put in the name of your subclass instead of the included JBossServletContextProvider.

In the application I am working on, we use a slight variant–we don’t use the Acegi JBoss Login module, and so when we get the Principal, we just get the Portal login name. So, our logic looks something like this: Get the Principal. See if there is an Authentication instance already in the session with a name that matches the login name. If there is no authentication instance, or if the authentication instance name does not match the portal login name, then get an authentication instance corresponding to the login name out of the database. Once we have the Authentication, either from the database or the session, we place that in the SecureContext and in the session. We then don’t have a httpSessionContextIntegrationFilter configured for Acegi, but rather proceed directly to the intercepting filter.

Book Review: Core Security Patterns: Best Practices and Strategies for J2EE(TM), Web Services, and Identity Management

Authors: Christopher Steel, Ramesh Nagappan, Ray Lai

Publisher: Prentice Hall / Sun Microsystems Press

ISBN: 0131463071 (Click to buy from Amazon)

When the Gang of Four wrote Design Patterns, they could be reasonably assured that most readers would know the basics of object oriented programming, and so they could spend their time on best practices when using objects. Similarly, when the authors of Core J2EE patterns wrote their book, they were able to assume that readers knew the basics of server side java, such as Requests, Sessions, and EJBs. However, the authors of Core Security Patterns made a different choice. They chose, correctly in my view, to assume no prior security knowledge. Consequently, the authors start with an introduction to basic security principals, including such details as the various types of encryption algorithms (symmetric and asymmetric, and for symmetric, block and stream), giving examples of each. They then give examples of how the various types of encryption algorithms are used, and detail how common protocols such as SSL make use of the algorithms. They show common means of attack, and how various security principles can prevent such attacks.

Once these basics of security are laid out, the authors spend several chapters describe how the various java security packages come together to implement the security described in chapter 2. A quick perusal of the topics of these chapters explains why several chapters are necessary–as it turns out, there is quite a bit of security functionality already built into standard J2Se and J2EE. For example, in J2SE 5, there are tools for key generation and management, for looking up revoked certificates, and of course for encryption and decryption, among other things. JAAS is covered here as well. The authors then cover web services and identity management, and how various XML security standards, such as XML Signature, can be used in both cases, and describe the java tools to work with such standards.

Finally, the authors move to the patterns themselves, and here the book finally becomes more like the standard patterns book, giving examples of the different scenarious under which you would use patterns, and providing the pros and cons of each. Since many readers will have taken advantage of the previous sections to learn about all the security technologies in depth for the first time, the patterns then provide a welcome companion, describing the proper use of the various technologies. There is nothing unique about the pattern presentation here, as compared to the other more well know pattern books–patterns are described and the pros and cons of each are given in depth, and so this part of the book may not get as much use. Still, just for the first part of the book alone, this book is worth reading.

Book Reviews: SOA Using Java Web Services, and J2EE Web Services: XML SOAP WSDL UDDI WS-I JAX-RPC JAXR SAAJ JAXP

Author: Mark D. Hansen

Publisher: Prentice Hall

ISBN: 0130449687 (Click to buy from Amazon)

Author: Richard Monson-Haefel

Publisher: Addison-Wesley

ISBN: 0321146182 (Click to buy from Amazon)

Given the big change from JAX-RPC to JAX-WS during the move from JEE 1.4 to JEE 5, and the fact that the SOA book covers JAX-WS while the older J2EE book covers JAX-RPC, it might seem that you would only need the newer SOA book. That assumption would be wrong. These two books are, in fact, quite complementary. The J2EE book provides, as its name suggests, a background of all the web service technologies, starting even with a background on XML. It then looks in depth at SOAP and WSDL, breaking apart what can be a complex and intimidating subject in the way that the author, Richard Monsel-Haefel, became famous for in his earlier EJB and JMS books. It moves to UDDI, and the use of JAXR as a way of interfacing with UDDI, giving examples of how to interface with public test UDDI servers. A section on SAAJ follows, describing how you can manipulate the soap message using the SAAJ api. There is a section on JAX-RPC, but that section is well contained, and can be safely skipped, assuming that you will also be reading the SOA book. Overall, this is the sort of high quality, comprehensive book we have come to expect from this author.

The SOA book, whether intentional or not, is an almost perfect companion to the J2EE book. It covers in depth the parts of the Java web service stack that have changed since the J2EE book came out, while not touching at all upon other parts of the stack. It then covers how to use these technologies for SOA. For example, JAXR, UDDI, and SAAJ have not changed since the time the J2EE book was written, and this book covers them not at all, except for describing how one part of SAAJ can be used for fault handling in SOA. On the other hand, JAX-WS is entirely new, and uses JAX-B as the serialization engine, and the book spends quite a bit of time on JAX-WS and JAX-B in particular. Annotations are another difference between JAX-WS and JAX-RPC, and the book lays out all the annotations and their effects upon the generation of WSDL, which is essential to know.

In addition to bring to reader up to speed on the latest on the Java Web Service stack, the book also devotes time to using these tools for SOA. Here, the author does a good job of explaining the theoretical basis for Java Web Services, and the theoretical basis for SOA, and describes the areas in which those two concepts are sometimes not a perfect match. He then provides enough information for the reader to decide how best to overcome these differences when they become apparent–For example, in extreme situations, a mapper XML tool, such as castor, may be used in place of a binder XML tool such as JAXB. Because of the two strengths of this book, it is recommended even if you not doing SOA, but merely want information on the latest Java Web Service tools. If you are also planning to do SOA, then this book becomes a must read.

Book Review: Core JavaServer Faces, Second Edition

Authors: David Geary – Cay Horstmann

Publisher: Sun Microsystems Press

ISBN: 978-0131738867 (Click to buy from Amazon)

Although JSF was first released in March of 2004, it has become more popular only recently. There are several reasons for the increased popularity:

1. Version 1.2 of the spec both adds some needed functionality and has a new, less buggy reference implementation.

2. The presence of new frameworks such as Ajax4JSF and ICEFaces, which add ajax functionality to JSF applications without the developer having to hand code any javascript.

3. New integration frameworks, such as Seam. One of the knocks against JSF was the fact that it seemed to add back in all the XML that we got rid of with EJB3, but Seam takes care of that.

To use the new frameworks, you’ll need a solid background in the theoretical aspects of JSF, with less time devoted to all the configuration options, since the integration frameworks will take care of that for you. Unfortunately, earlier JSF books took the opposite approach–configuration accounted for a great deal of their content. Fortunately, this book, published after the new frameworks came out, spends a great deal of time on explaining the reasoning behind the design of JSF, and how you can use that knowledge in your own application, and how the new frameworks tie into JSF. Armed with this theoretical knowledge, the authors can also explain the reason behind some of the limitations of the various frameworks. Configuration options are still covered, but in a more succinct way.

The most important theoretical piece of information to know about JSF is the lifecycle of a request–

  1. Restore view
  2. Apply request values; process events
  3. Process validations; process events
  4. Update model values; process events
  5. Invoke application; process events
  6. Render response

One of the advantages of JSF over other, earlier frameworks is that the phases have been explicitly defined and exposed to the developer. The authors take the phases as their guide for how to explain JSF, and this approach works well, as they show what you, the developer, can do at each phase to help accomplish the goals you have for your application.

For now, this is the book to get if you are working with JSF in any capacity.

Book Review: Object Oriented Analysis and Design with Applications, Third Edition

<Authors: Grady Booch, Robert A Maksimchuk, Michael W. Engle, Bobbi J. Young, Jim Conallen, Kelli A. Houston

Publisher: Addison-Wesley. Part of the Addison-Wesley Object Technology Series

ISBN: 978-0201895513 (Click to buy from Amazon)

This book covers how one should go about designing object oriented software, assuming no prior object oriented experience. It takes as its mission not only the purely technical aspects of that task, but also delves into requirements gathering, to ensure that the object oriented software delivered at the end is actually something the customer wants.

Some time ago, our company started work on a new software product. We had just begun designing the object model when I was given this book to review. This circumstance presented a great opportunity to not only read about object oriented design, but also to immediately apply the concepts, and see if those concepts actually worked in practice. I found that this book had three primary strengths.

The first strength is that when presenting a particular concept, the history of both that concept and the alternatives to that concept are presented. This allows the user to see why a particular concept is recommended over others, so that the user does not need to repeat the mistakes of past object oriented practitioners. For example, they trace the development of programming languages as they became more and more object oriented, showing why certain features were added to languages and the functionality that such features enabled, and how such features should be used.

The second strength is the advice the authors give in helping the user develop an object model. The authors quickly disabuse one of the notion that it easy to come up with a great object model on the first try. Instead, the authors state that developing a great object model is hard work, and the model will undergo transitions and become better as a project progresses. Specifically, they say “The best software designs look simple, but as experience shows, it takes a lot of hard work to design a simple architecture”. They continue by comparing the correct classification of logic and state into proper classes as part of a broader problem of classification in general that has been with us since Aristotle first classified plants and animals, and was continued through Aquinas, Descartes, and Locke. While this history of classification didn’t help me design an object model any faster, it at least made me feel better to know that it’s a problem that is known to be hard.

Even though object design is a hard problem, the authors do provide ways to help, by giving heuristics for development. They advocate an iterative approach to design, by gathering requirements and then gradually adding the requirements into the project. Doing so allows quick feedback as to the suitability of the model, allowing it to be easily changed.

The third strength is that in the latter half of the book, the authors attempt to apply the ideas given in the first part of the book to real projects. The value of this part of the book is not in looking at the resulting project, but rather in their explanations of how they attempt to correctly apply the ideas to the projects. For example, when building a web application, they use EJB 2.x, complete with the EJB interfaces, Facades, DTOs, and so on. While a new project started today would probably not make that technology choice, most of the time spent by the authors in this web application is not spent on these technology details, but rather on how the requirements were gathered, and how those requirements translated into the object model. Such information is useful no matter what the underlying technology.

One of the questions to be answered when reviewing a book for the Austin Java Users Group is “Is there an existing, canonical book that already covers the same ground.” This struck me as interesting, because this book itself is the canonical book for object oriented analysis and design. Its constant references to current literature (the bibliography is 73 pages long) help to assure the reader that he or she is actually using research proven methods to properly construct object models that will be useful, flexible, and correct. Recommended.