dev@javaserverfaces.java.net

Re: Components opting into attributesThatAreSet feature

From: Mark Collette <mark.collette_at_icesoft.com>
Date: Tue, 04 Nov 2008 18:11:43 -0700

I should probably give an example. Let's look at HtmlSelectOneListbox
(randomly selected):

    private static final String[] STATE_NAMES = new String[] {
        "accesskey",
        "dir",
        "disabled",
        "disabledClass",
        "enabledClass",
        "label",
        "lang",
        "onblur",
        "onchange",
        "onclick",
        "ondblclick",
        "onfocus",
        "onkeydown",
        "onkeypress",
        "onkeyup",
        "onmousedown",
        "onmousemove",
        "onmouseout",
        "onmouseover",
        "onmouseup",
        "onselect",
        "readonly",
        "size",
        "style",
        "styleClass",
        "tabindex",
        "title"
    };

    public void restoreState(FacesContext _context, Object _state) {
        _values = (Object[]) _state;
        super.restoreState(_context, _values[0]);
        this.accesskey = (java.lang.String) _values[1];
        this.dir = (java.lang.String) _values[2];
        this.disabled = (java.lang.Boolean) _values[3];
        this.disabledClass = (java.lang.String) _values[4];
        this.enabledClass = (java.lang.String) _values[5];
        this.label = (java.lang.String) _values[6];
        this.lang = (java.lang.String) _values[7];
        this.onblur = (java.lang.String) _values[8];
        this.onchange = (java.lang.String) _values[9];
        this.onclick = (java.lang.String) _values[10];
        this.ondblclick = (java.lang.String) _values[11];
        this.onfocus = (java.lang.String) _values[12];
        this.onkeydown = (java.lang.String) _values[13];
        this.onkeypress = (java.lang.String) _values[14];
        this.onkeyup = (java.lang.String) _values[15];
        this.onmousedown = (java.lang.String) _values[16];
        this.onmousemove = (java.lang.String) _values[17];
        this.onmouseout = (java.lang.String) _values[18];
        this.onmouseover = (java.lang.String) _values[19];
        this.onmouseup = (java.lang.String) _values[20];
        this.onselect = (java.lang.String) _values[21];
        this.readonly = (java.lang.Boolean) _values[22];
        this.size = (java.lang.Integer) _values[23];
        this.style = (java.lang.String) _values[24];
        this.styleClass = (java.lang.String) _values[25];
        this.tabindex = (java.lang.String) _values[26];
        this.title = (java.lang.String) _values[27];
        handleAttributes(STATE_NAMES, _values);
    }

    private void handleAttribute(String name, Object value) {
            List<String> setAttributes = (List<String>)
this.getAttributes().get("javax.faces.component.UIComponentBase.attributesThatAreSet");
            if (setAttributes == null && value != null) {
                setAttributes = new ArrayList<String>(6);
                
this.getAttributes().put("javax.faces.component.UIComponentBase.attributesThatAreSet",
setAttributes);
            }
            if (value == null) {
                setAttributes.remove(name);
            } else if (!setAttributes.contains(name)) {
                setAttributes.add(name);
            }
    }

    private void handleAttributes(String[] names, Object[] values) {
        List<String> setAttributes = (List<String>)
this.getAttributes().get("javax.faces.component.UIComponentBase.attributesThatAreSet");
        for(int i = 1; i < values.length; i++) {
            Object value = values[i];
            if(value != null) {
                if (setAttributes == null) {
                    setAttributes = new ArrayList<String>(6);
                    
this.getAttributes().put("javax.faces.component.UIComponentBase.attributesThatAreSet",
setAttributes);
                }
                String name = names[i-1];
                if (!setAttributes.contains(name)) {
                    setAttributes.add(name);
                }
            }
        }
    }

Also, where we state save the ValueExpressions, there would be something
similar to handleAttributes(-).


Mark Collette
ICEsoft Technologies, Inc.
http://mark-icefaces-reflections.blogspot.com/


Mark Collette wrote:

> It's probably more likely that developers will extend a stock JSF
> component, to add a simple behaviour, and want that to remain
> performant, than the case where they will create a component from
> scratch that couldn't make use of this optimisation.
>
> But that does bring up the point, why state save the List? Can't it be
> derived by the existing restoreState code?
>
>
> Ryan Lubke wrote:
>
>> Mark Collette wrote:
>>
>>> Maybe the list could always track the set attributes, without
>>> requiring the component be a stock JSF component? It would just be
>>> the pass-through attribute rendering code that would impose the
>>> limitation, that it would only use the list for stock JSF components?
>>
>>
>> Would like to have a way to say what components so we don't force a
>> state saving penalty on those component sets that don't depend on an
>> implementation specific feature.
>>
>>> Ryan Lubke wrote:
>>>
>>>> Mark Collette wrote:
>>>>
>>>>> Are there any limitations on adding public or protected methods
>>>>> into UIComponent or UIComponentBase?
>>>>
>>>>
>>>>
>>>> Yes, it can't be done as the TCK signature tests would fail the build.
>>>>
>>>> Any changes to the API (public or protected) must be backed by the
>>>> specification.
>>>>
>>>>> Ryan Lubke wrote:
>>>>>
>>>>>> Mark Collette wrote:
>>>>>>
>>>>>>> Is there any way for third party components to opt into making
>>>>>>> use of the attributesThatAreSet feature?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Probably not given the changes that were made for this feature in
>>>>>> 1.2_10.
>>>>>>
>>>>>>> Or any plans to facilitate that, in the future?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> No plans at this point. Patches are welcome.
>>>>>>
>>>>>>>
>>>>>>>