+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
