[JAVASERVERFACES-2244] UIInput and UIData create unnecessary state array Created: 13/Nov/11  Updated: 02/Nov/12  Resolved: 02/Aug/12

Status: Closed
Project: javaserverfaces
Component/s: state saving
Affects Version/s: 2.1.3, 2.1.4
Fix Version/s: None

Type: Bug Priority: Major
Reporter: arjan tijms Assignee: Manfred Riem
Resolution: Fixed Votes: 10
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Text File jsf22trunk_statearrays.patch    
Issue Links:
Related
is related to JAVASERVERFACES-2486 UIInput creates unnecessary state arrray Closed
is related to JAVASERVERFACES-2487 UIData creates unnecessary state array Closed
Tags: performance

 Description   

Similar to issue JAVASERVERFACES-2203, UIInput and UIData also create unnecessary state arrays:

The most obvious is UIInput:

UIInput.java
public Object saveState(FacesContext context) {

    if (context == null) {
        throw new NullPointerException();
    }
    Object[] values = null;
    if (values == null) {
        values = new Object[4];
    }

    values[0] = super.saveState(context);
    values[1] = emptyStringIsNull;
    values[2] = validateEmptyFields;
    values[3] = ((validators != null) ? validators.saveState(context) : null);
    return (values);
 }

Should become something like:

UIInput.java
 public Object saveState(FacesContext context) {

        if (context == null) {
            throw new NullPointerException();
        }
        
        Object[] values = null;
        Object superState = super.saveState(context);
        Object attachedState = ((validators != null) ? validators.saveState(context) : null);

        if (superState != null || emptyStringIsNull != null || validateEmptyFields != null || attachedState != null) {
            values = new Object[] {superState, emptyStringIsNull, validateEmptyFields, attachedState};
        }

        return (values);
 }

UIData is a little less obvious. It has a guard, but still calculates the super state twice and the part where the state has not been marked does suffer directly from the problem.

UIData.java
 @Override
 public Object saveState(FacesContext context)
 {
    if (initialStateMarked())
    {
        Object parentSaved = super.saveState(context);
        if (parentSaved == null &&_rowDeltaStates.isEmpty())
        {
            return null;
        }
        else
        {
            Object values[] = new Object[2];
            values[0] = super.saveState(context);
            values[1] = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
            return values; 
        }
    }
    else
    {
            Object values[] = new Object[2];
            values[0] = super.saveState(context);
            values[1] = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
            return values;
    }
}

Could become:

UIData.java
 public Object saveState(FacesContext context) {
       
       Object superState = super.saveState(context);
       if (initialStateMarked() && superState == null && _rowDeltaStates.isEmpty()) {        
           return null;
       } 
       
       Object values[] = null;          
       Object attachedState = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
       if (superState != null || attachedState != null) {
           values = new Object[] {superState, attachedState};
       }
               
       return values;    
 }

UIViewRoot has the guard now, but still defines values as an instance variable. In changeset 8600 Ed Burns had moved the same variable in UIInput to a local variable. It's perhaps better to do that here as well.

I've attached a patch against the mojarra trunk (2.2). All tests pass after the patch, although one test had to be modified (a test that checks the returned state array for attached state now has to test the entire array for null instead of the third element).



 Comments   
Comment by arjan tijms [ 03/Dec/11 ]

Some additional concern is that's it's maybe questionable if UIInput's emptyStringIsNull and validateEmptyFields should really be in view state? They seem to be global concerns and not a per component thing. Perhaps storing these in application scope is a better approach?

Comment by Manfred Riem [ 02/Aug/12 ]

Tracking as 2 separate issues

Comment by Manfred Riem [ 03/Aug/12 ]

Changes for UIInput are done

Generated at Tue Jun 30 06:07:27 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.