myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sochor Zdeněk <zdenek.soc...@ataco.cz>
Subject Re: [Myfaces Wiki] Update of "Code Generation" by SimonKitching
Date Fri, 01 Feb 2008 16:56:01 GMT
Hi,

Martin Marinschek napsal(a):
> Hi Zdenek,
>
>   
>> A question was raised about why state isn't retrieved from the
>> attributes map - this cannot be used, however, cause it would use
>> reflection internally and call the getter of the method, if a value is
>> not directly stored in the attributes map. As soon as the getter is
>> called, after the check for the local value returns null, you will get
>> back the value from a value-expression, and you do not want to save this
>> value in the state, as the value-expression itself is already stored!
>>     
>
> so you want to get rid of the concept of a local value completely, and
> store everything in the attribute map? Now I see. This might actually
> work, yes.
>
>   
1. getting rid of attributes' local values - yes,
2. getting rid of most getters/setters w/o special code in them (as 
typical use today)

2 should be possible with JSP tags, don't know about Facelets (maybe 
tag-handlers could do this)

 From spec and API's JavaDoc i got this idea of processing attributes:

reading:
- check if special getter -> use it (if it looks at Map/VB is optional)
- check if in map -> use it
- check if value binded -> resolve and use it (or use default in some cases)

writing:
- check if special setter -> use it AND
- store in map

using in lifecycle's process:
- Restore view:
   - restore Map (done by ancester in API)
- Apply Request:
  - resolve all ValueBindings and store them in Map to avoid multiple 
resolving
     - basically reading all attributes defined in tld and still not in Map
  This should make this work for Mojarra's all getter/setter way (if 
"forgot" writing values into Map)
   - possible optimization could be in "lazy" fetching attributes when 
needed (once fetched, store in Map)
  To avoid saving these generated attributes' values, add/alter special 
key in Map (e.g. "o_a_m_generatedAttributes") with array containing 
names of those attributes
- next phases:
  - use values from Map (if not lazily fetched already complete, adding 
new entries when not along with modifications of special key's value)
    - NOT using reading of attributes as above if already in Map
  - writing attributes as above and if attribute's name present in 
special key's array, remove it from that array
     - any direct modifications w/o deletion in array (e.g. for internal 
processing) made in Map's values of generated attributes will be ignored 
in state saving
- Render Response:
  - clean Map of generated stuff:
      - remove all entries with null value
      - remove all entries with names in special key's array
      - remove special key
  - saving Map (done by ancester in API)

Having attributes both in Map and local properties (as of today and 
present in API) is not an obstruction - values in local properties take 
precedence,
because Map is stored/restored first.

Using this could possibly make any kind of generator for COMPONENT 
classes needless - all generic code for all attributes would be written 
once.

Only setters/getters i'd like to see in components' classes are with 
special behaviour code (but still using Map in the end).

Tasks in this approach:
- generating TAGS (JSP and Facelets)
- create utility class for
  a) getting values from Map to use in component's methods, e.g:
  static public Boolean getBoolean(UIComponent comp, String attr, 
Boolean default) {
     Object res = comp.getAttributes().get(attr);
     if (obj != null) return (Boolean)res;
     // check if in special key - it may got resolved to null -> return 
default
     // not in special key -> resolve it, add to Map (along with adding 
to special key's array)
     // resolved != null ? return (Boolean)resolved : default;
  }
  (I think default can be got from TLD for JSF 1.2)
  b) setting values to Map, e.g.
  static public void setBoolean(UIComponent comp, String attr, Boolean 
value) {
    // if special setter, use it
     comp.getAttributes().put(attr, value);
     if (comp.getAttributesMap().get("o_a_m_generatedAttributes") != null) {
      // remove attr from array
    }
  }

This way it would be only in Tag class/TLD to define new attributes 
which would be automatically saved/restored.
(This also fulfills JSF 1.1 spec in handling generic atributes from 
section 3.1.10)

OR (to be really on business of thread):

With this approach it would be pretty easy to support one method of 
generating libs:
Annotations (or XDoclet) written for component class defining attributes 
- name, type, default value, target language, description...
This annotation should inherit all definitions from component's parent 
class.
- this way developer can really see which attributes he can really use 
in component's code AND
- the class is compilable on it's own (it's accessing already existing Map)


Regards,
  Zdenek
> regards,
>
> Martin
>
>
>   

Mime
View raw message