+1, i think it's slick little addition that could come in handy when needed.
code looks good, how about changing the actionbean parameter type in
saveFields, restoreFields and getSessionFields to Class<? extends
ActionBean>?

also (and i realize this might be a bit out of scope for this
interceptor), how about sharing the same session variable between
actionbeans? could this be done by adding an additional fieldKey
attribute, overwriting your standard MyActionBean#FieldName?
OTOH, that might result in namespace clashes..

Newman, John W wrote:
> If this is well tested & stable I vote for merging it in the stripes core, I 
> will certainly be using it.
> 
> @Session
> private Object o;
> 
> is a lot easier than adding methods to the context and the interceptor 
> methods to do it.  I like it.
> 
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Poitras 
> Christian
> Sent: Monday, November 05, 2007 10:17 AM
> To: Stripes Development List
> Subject: Re: [Stripes-dev] Session annotation
> 
> Hi.
> 
> I updated my interceptor and annotation and I think I'm very close to a final 
> version. I included my classes in this email.
> I don't use my custom ActionBeanContext anymore so anyone can try using it!
> 
> I decided to keep the ConcurrentHashMap. I known it stinks for garbage 
> collection, but 2 threads could access the same key (ActionBean class) at the 
> same time...
> Any idea on how I could change the static ConcurrentHashMap to improve 
> garbage collection is welcome.
> 
> Christian
> 
> 
> -----Original Message-----
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Kai Grabfelder
> Sent: Sunday, November 04, 2007 6:20 AM
> To: Stripes Development List
> Subject: Re: [Stripes-dev] Session annotation
> 
> Hi Christian,
> 
> ask Tim to create an account for you (it's best to use the private contact 
> address that can be found in the wiki). If you want to you can also send me 
> the content(in confluence syntax) and I can add it. Unfortunately I can't 
> create the account for you by myself...
> 
> cheers
> Kai
> 
> --- Original Nachricht ---
> Absender: Poitras Christian
> Datum: 02.11.2007 16:56
>> Hi Jasper!
>>
>> 1- Indeed, the the serializable and maxTime attributes are used in my 
>> ActionBeanContext (since the save/restore code was there at first). 
>> I will move the code from my ActionBeanContext to Interceptor before posting 
>> it. This is one of the things I need to change...
>> 2- Using a WeakHashMap is a good idea. I used this based on 
>> BeforeAfterMethodIntercetor (I may have missed something in that 
>> interceptor...).
>> 3- This appears to be a bug I didn't hit yet! Thanks for the correction!
>>
>> I will need to do some updates to the code, but I wanted to share the idea 
>> at first.
>> I will create a wiki page. How do I register to create a page?
>>
>> Christian
>>
>>
>> -----Original Message-----
>> From: [EMAIL PROTECTED]
>> [mailto:[EMAIL PROTECTED] On Behalf 
>> Of Jasper Fontaine
>> Sent: Friday, November 02, 2007 11:42 AM
>> To: Stripes Development List
>> Subject: Re: [Stripes-dev] Session annotation
>>
>> Good stuff
>> In our project we don't need this right now, but it might be a useful 
>> addition later.
>>
>> 3 things:
>>
>> - There's no code in the interceptor that uses the serializable and maxTime 
>> attributes, right?
>>
>> - Wouldn't it be better to use a WeakHashMap? It's not like two 
>> persons will access the same session at the same time ;)
>>
>> - Shouldn't this block
>>
>> // If value is null and field is primitive, don't set value.
>> if (value != null || !field.getType().isPrimitive()) {
>>      field.set(actionBean, value);
>> }
>>
>> be changed to:
>>
>> // If value is null or field is primitive, don't set value.
>> if (value != null && !field.getType().isPrimitive()) {
>>      field.set(actionBean, value);
>> }
>>
>>
>> Like the extended formtag for SSL, i think this would be a nice little piece 
>> of code to add to the Wiki (as opposed to adding a patch to JIRA). 
>> Anybody knows if that's possible yet, and if yes, how to do it?
>>
>> -j
>>
>> Poitras Christian wrote:
>>> Hi John!
>>>  
>>> That is very close to what I've done.
>>> I was tired of typing code to save every fields I wanted, so I added 
>>> an annotation to use one generic save/restore method automatically.
>>>  
>>> /**
>>> * Selected sample.
>>> */
>>> @Session
>>> *private* List<Sample> sampleList;
>>>  
>>> Just adding an annotation will automatically save the field and 
>>> restore it with an interceptor.
>>> I don't think this will interest many people, but sharing addition to 
>>> open source is something I like.
>>>  
>>> Here's the basic interceptor idea. Save all @Session fields on 
>>> Resolution. Restore all @Session fields on ActionBean resolution.
>>> I need to change a small code part before submitting it to users.
>>>  
>>> /**
>>> * Interceptor that stores or restores session objects.
>>> *
>>> * [EMAIL PROTECTED] poitrac
>>> */
>>> @Intercepts(value={LifecycleStage./ActionBeanResolution/,
>>> LifecycleStage./ResolutionExecution/})
>>> public class SessionStoreInterceptor implements Interceptor {
>>>  
>>> /** Lazily filled in map of Class to fields annotated with Session. 
>>> */
>>> *private* *static* Map<Class<?>, Collection<Field>> /fieldMap/ =
>>> *new* ConcurrentHashMap<Class<?>, Collection<Field>>();
>>>  
>>> /* (non-Javadoc)
>>> * @see
>>> net.sourceforge.stripes.controller.Interceptor#intercept(net.sourcefo
>>> r
>>> ge.stripes.controller.ExecutionContext)
>>> */
>>> *public* Resolution intercept(ExecutionContext context) *throws* 
>>> Exception { // Continue on and execute other filters and the lifecycle code.
>>> Resolution resolution = context.proceed();
>>>  
>>> // Get all fields with session.
>>> Collection<Field> fields =
>>> /getSessionFields/(context.getActionBean().getClass());
>>>  
>>> // Restores values from session.
>>> *if*
>>> (LifecycleStage./ActionBeanResolution/.equals(context.getLifecycleSta
>>> g
>>> e()))
>>> {
>>> *this*.restoreFields(fields, context.getActionBean(), 
>>> (WebContext)context.getActionBeanContext());
>>> }
>>> // Store values in session.
>>> *if*
>>> (LifecycleStage./ResolutionExecution/.equals(context.getLifecycleStag
>>> e
>>> ())) { *this*.saveFields(fields, context.getActionBean(), 
>>> (WebContext)context.getActionBeanContext());
>>> }
>>>  
>>> *return* resolution;
>>> }
>>>  
>>> /**
>>> * Saves all fields in session.
>>> * [EMAIL PROTECTED] fields Fields to save in session.
>>> * [EMAIL PROTECTED] actionBean ActionBean.
>>> * [EMAIL PROTECTED] context WebContext.
>>> * [EMAIL PROTECTED] IllegalAccessException Cannot get access to some fields.
>>> */
>>> *protected* *void* saveFields(Collection<Field> fields, ActionBean 
>>> actionBean, WebContext context) *throws* IllegalAccessException {
>>> *for* (Field field : fields) {
>>> *if* (!field.isAccessible()) {
>>> field.setAccessible(*true*);
>>> }
>>> context.set(getFieldKey(field), field.get(actionBean), 
>>> ((Session)field.getAnnotation(Session.*class*)).serializable(),
>>> ((Session)field.getAnnotation(Session.*class*)).maxTime());
>>> }
>>> }
>>> /**
>>> * Restore all fields from value stored in session.
>>> * [EMAIL PROTECTED] fields Fields to restore from session.
>>> * [EMAIL PROTECTED] actionBean ActionBean.
>>> * [EMAIL PROTECTED] context WebContext.
>>> * [EMAIL PROTECTED] IllegalAccessException Cannot get access to some fields.
>>> */
>>> *protected* *void* restoreFields(Collection<Field> fields, ActionBean 
>>> actionBean, WebContext context) *throws* IllegalAccessException {
>>> *for* (Field field : fields) {
>>> *if* (!field.isAccessible()) {
>>> field.setAccessible(*true*);
>>> }
>>> Object value = context.get(getFieldKey(field)); // If value is null 
>>> and field is primitive, don't set value.
>>> *if* (value != *null* || !field.getType().isPrimitive()) { 
>>> field.set(actionBean, value); } } }
>>>  
>>>  
>>>
>>>  
>>> ---------------------------------------------------------------------
>>> -
>>> --
>>> *From:* [EMAIL PROTECTED]
>>> [mailto:[EMAIL PROTECTED] *On Behalf 
>>> Of *Newman, John W
>>> *Sent:* Friday, November 02, 2007 11:06 AM
>>> *To:* Stripes Development List
>>> *Subject:* Re: [Stripes-dev] Session annotation
>>>
>>> Hi,
>>>
>>>  
>>>
>>> What I've typically done for this is the following:
>>>
>>>  
>>>
>>> Class ActionBean  {
>>>
>>>     DateRange dateFilter;
>>>
>>>  
>>>
>>>  
>>>
>>>     @Before(stages={LifecycleStage.BindingAndValidation})
>>>
>>>     void prepareBean()  {
>>>
>>>       setDateFilter(getContext().getDateFilter());
>>>
>>>     }
>>>
>>>  
>>>
>>>  
>>>
>>>    @Before(stages={LifecycleStage.ResolutionExecution})
>>>
>>>     Void saveBean()  {
>>>
>>>       getContext().setDateFilter(getDateFilter());
>>>
>>>     }
>>>
>>> }
>>>
>>>  
>>>
>>> class ActionBeanContext  {
>>>
>>>      DateRange getDateFilter()  {
>>>         return (DateFilter)
>>> getSessionAttribute(AttrNames.SES_DATE_FILTER);
>>>
>>>      }
>>>
>>>   
>>>
>>>     void setDateFilter(DateRange dateFilter)  {
>>>
>>>        setSessionAttribute(AttrNames.SES_DATE_FILTER, dateFilter);
>>>
>>>     }
>>>
>>> }
>>>
>>>  
>>>
>>> Those interceptor methods pull it out of the context before binding, 
>>> the binding phase potentially overwrites it if something came in via 
>>> the post, and whatever is in the bean gets sent back out to the 
>>> context before the page is displayed.  easy
>>>
>>>  
>>>
>>> John
>>>
>>>  
>>>
>>> *From:* [EMAIL PROTECTED]
>>> [mailto:[EMAIL PROTECTED] *On Behalf 
>>> Of *Poitras Christian
>>> *Sent:* Friday, November 02, 2007 10:09 AM
>>> *To:* [email protected]
>>> *Subject:* [Stripes-dev] Session annotation
>>>
>>>  
>>>
>>> Hi!
>>>
>>>  
>>>
>>> I've added an annotation and an interceptor to Stripes to store 
>>> ActionBean fields in session and restore them automatically on 
>>> subsequent requests.
>>>
>>> I wanted to share this "plugin" with people of stripes. Where can I 
>>> post such information and classes.
>>>
>>>  
>>>
>>> The annotation is below.
>>>
>>> Christian
>>>
>>>  
>>>
>>>  
>>>
>>> /*
>>>  * <p>Copyright: Copyright (c) 2007</p>
>>>  * <p>Company: Institut de recherches cliniques de Montréal 
>>> (IRCM)</p> */ package ca.qc.ircm.lims.web.annotation;
>>>
>>>  
>>>
>>> import java.lang.annotation.ElementType; import 
>>> java.lang.annotation.Retention; import 
>>> java.lang.annotation.RetentionPolicy;
>>> import java.lang.annotation.Target;
>>>
>>>  
>>>
>>> /**
>>>  * Annotation used to indicate that an attribute should be stored in 
>>> session.
>>>  *
>>>  * @author poitrac
>>>  */
>>> @Retention(RetentionPolicy.RUNTIME)
>>> @Target(ElementType.FIELD)
>>> public @interface Session {
>>>     /**
>>>      * Indicate if attribute is serializable.
>>>      */
>>>     boolean serializable() default false;
>>>     /**
>>>      * Maximum time in minutes the object will stay in session if not 
>>> accessed.
>>>      */
>>>     int maxTime() default -1;
>>> }
>>>
>>>  
>>>
>>>  
>>>
>>>
>>> ---------------------------------------------------------------------
>>> -
>>> --
>>>
>>> ---------------------------------------------------------------------
>>> -
>>> --- This SF.net email is sponsored by: Splunk Inc.
>>> Still grepping through log files to find problems?  Stop.
>>> Now Search log events and configuration files using AJAX and a browser.
>>> Download your FREE copy of Splunk now >> http://get.splunk.com/
>>>
>>>
>>> ---------------------------------------------------------------------
>>> -
>>> --
>>>
>>> _______________________________________________
>>> Stripes-development mailing list
>>> [email protected]
>>> https://lists.sourceforge.net/lists/listinfo/stripes-development
>>
>> ----------------------------------------------------------------------
>> --- This SF.net email is sponsored by: Splunk Inc.
>> Still grepping through log files to find problems?  Stop.
>> Now Search log events and configuration files using AJAX and a browser.
>> Download your FREE copy of Splunk now >> http://get.splunk.com/ 
>> _______________________________________________
>> Stripes-development mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/stripes-development
>>
>> ----------------------------------------------------------------------
>> --- This SF.net email is sponsored by: Splunk Inc.
>> Still grepping through log files to find problems?  Stop.
>> Now Search log events and configuration files using AJAX and a browser.
>> Download your FREE copy of Splunk now >> http://get.splunk.com/ 
>> _______________________________________________
>> Stripes-development mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/stripes-development
>>
> 
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >> http://get.splunk.com/ 
> _______________________________________________
> Stripes-development mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/stripes-development
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >> http://get.splunk.com/ 
> _______________________________________________
> Stripes-development mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/stripes-development
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >> http://get.splunk.com/
> _______________________________________________
> Stripes-development mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/stripes-development
> 



-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to