001    /*
002      Copyright (C) 2001-2002 Renaud Pawlak <renaud@aopsys.com>
003                              Laurent Martelli <laurent@aopsys.com>
004    
005      This program is free software; you can redistribute it and/or modify
006      it under the terms of the GNU Lesser General Public License as
007      published by the Free Software Foundation; either version 2 of the
008      License, or (at your option) any later version.
009    
010      This program is distributed in the hope that it will be useful,
011      but WITHOUT ANY WARRANTY; without even the implied warranty of
012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013      GNU Lesser General Public License for more details.
014    
015      You should have received a copy of the GNU Lesser General Public License
016      along with this program; if not, write to the Free Software
017      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
018    
019    package org.objectweb.jac.aspects.session;
020    
021    import java.util.*;
022    import org.aopalliance.intercept.ConstructorInvocation;
023    import org.aopalliance.intercept.MethodInvocation;
024    import org.apache.log4j.Logger;
025    import org.objectweb.jac.core.*;
026    import org.objectweb.jac.core.Collaboration;
027    import org.objectweb.jac.util.*;
028    
029    /**
030     * This wrapper handles the session for each object within the JAC system.
031     *
032     * @see #handleSession(Interaction)
033     * @author Renaud Pawlak */
034    
035    public class SessionWrapper extends Wrapper {
036        static Logger logger = Logger.getLogger("session");
037    
038            /** Stores the sessions and their contextual attributes (sid ->
039                saved attributes). */
040            protected static Hashtable sessions = new Hashtable();
041    
042            /** Stores the applications (sid -> applicationName) */
043            protected static Hashtable applications = new Hashtable();
044    
045            public SessionWrapper(AspectComponent ac) {
046                    super(ac);
047            }
048    
049            /**
050             * Removes a session attribute.
051             *
052             * <p>The given attribute will be forgotten for the current
053             * interaction and for all the forthcoming interactions of the same
054             * session. This can be used for instance to log-out a user.
055             *
056             * @param name the name of the attribute to forget */
057    
058            public void clearCurrentSessionAttribute(String name) {
059                    String sid = (String) attr(SessionAC.SESSION_ID);
060                    if (sid == null) {
061                            logger.debug("clearCurrentSessionAttribute: no Session_ID found");
062                            return;
063                    }
064                    logger.debug("clearCurrentSessionAttribute for session " + sid);
065                    Hashtable attrs = (Hashtable) sessions.get(sid);
066                    if (attrs != null) {
067                            attrs.remove(name);
068                    }
069                    Collaboration.get().removeAttribute(name);
070            }
071    
072            /**
073             * Handles sessions for the wrapped method.
074             *
075             * <p>The session handling algorithm is:
076             *
077             * <ul>
078             *   <li>if the session id - <code>attr("Session.sid")</code> - 
079             *       is not defined, do nothing</li>
080             *   <li>try to restore the saved context attributes for this session id 
081             *       if already saved</li>
082             *   <li>else save them into the <code>sessions</code> field</li>
083             * </ul>
084             *
085             * @return the wrapped method return value
086             */
087    
088            public Object handleSession(Interaction interaction) {
089    
090                    Object result = null;
091    
092                    String sid = (String) attr(SessionAC.SESSION_ID);
093    
094                    if (attr(SessionAC.INITIALIZED) != null) {
095    
096                            logger.debug("session initiliazed for "
097                             +interaction.wrappee+"."+ interaction.method);
098    
099                // I believe we do not need this (Laurent)
100                /*
101                            if (applications.containsKey(sid)) {
102                                    Log.trace("application",
103                              "retreiving cur app from session: "
104                              + (String) applications.get(sid));
105                    if (!applications.get(sid).equals(Collaboration.get().getCurApp()))
106                        Log.warning("curr app changed from "+Collaboration.get().getCurApp()+" to "+applications.get(sid));
107                                    Collaboration.get().setCurApp((String) applications.get(sid));
108                            }
109                */
110    
111                            result = proceed(interaction);
112    
113                /*
114                            if (applications.containsKey(sid)) {
115                                    Log.trace("application",
116                              "retreiving cur app from session: "
117                              + (String) applications.get(sid));
118                    if (!applications.get(sid).equals(Collaboration.get().getCurApp()))
119                        Log.warning("curr app changed from "+Collaboration.get().getCurApp()+" to "+applications.get(sid));
120                                    Collaboration.get().setCurApp((String) applications.get(sid));
121                            }
122                */
123    
124                            return result;
125    
126                    }
127    
128                    logger.debug("handling session for "
129                         + interaction.wrappee + "." + interaction.method);
130            
131                    if (sid == null) {
132                            logger.debug("session is not defined by client");
133                            return proceed(interaction);
134                    }
135    
136                    if (applications.containsKey(sid)) {
137                            logger.debug("retreiving cur app from session: "
138                             + (String) applications.get(sid));
139                            Collaboration.get().setCurApp((String) applications.get(sid));
140                    }
141    
142                    logger.debug("in session, application=" + Collaboration.get().getCurApp());
143    
144                    logger.debug("found session " + sid + " for " + interaction.method.getName());
145                    Hashtable savedAttributes = null;
146    
147                    if (sessions.containsKey(sid)) {
148                            savedAttributes = (Hashtable) sessions.get(sid);
149                    } else {
150                            savedAttributes = new Hashtable();
151                            sessions.put(sid, savedAttributes);
152                    }
153    
154                    String[] storedAttributes =
155                            ((SessionAC) getAspectComponent()).getStoredAttributes();
156    
157                    for (int i = 0; i < storedAttributes.length; i++) {
158                            if (savedAttributes.containsKey(storedAttributes[i])) {
159                                    logger.debug("reading "+ storedAttributes[i]
160                                 + "=" + savedAttributes.get(storedAttributes[i])
161                                 + " for " + interaction.method.getName());
162                                    Collaboration.get().addAttribute(
163                                            storedAttributes[i],
164                                            savedAttributes.get(storedAttributes[i]));
165                            }
166                    }
167    
168                    attrdef(SessionAC.INITIALIZED, "true");
169    
170                    result = proceed(interaction);
171    
172                    for (int i = 0; i < storedAttributes.length; i++) {
173                            if (Collaboration.get().getAttribute(storedAttributes[i])
174                                    != null) {
175                                    logger.debug("saving " + storedAttributes[i]
176                                 + "=" + Collaboration.get().getAttribute(storedAttributes[i])
177                                 + " for " + interaction.method.getName());
178                                    savedAttributes.put(
179                                            storedAttributes[i],
180                                            Collaboration.get().getAttribute(storedAttributes[i]));
181                            } else {
182                                    logger.debug("NOT saving " + storedAttributes[i] 
183                                 + "=" + Collaboration.get().getAttribute(storedAttributes[i])
184                                 + " for " + interaction.method.getName());
185                            }
186                    }
187                    String application = Collaboration.get().getCurApp();
188                    if (application != null) {
189                            logger.debug("session saves app");
190                            applications.put(sid, application);
191                    }
192                    return result;
193            }
194    
195            public Object invoke(MethodInvocation invocation) throws Throwable {
196                    return handleSession((Interaction) invocation);
197            }
198    
199            public Object construct(ConstructorInvocation invocation)
200                    throws Throwable {
201                    return handleSession((Interaction) invocation);
202            }
203    
204    }