View Javadoc

1   package org.apache.turbine.pipeline;
2   
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21   */
22  
23  
24  import java.io.IOException;
25  import java.util.ArrayList;
26  import java.util.Enumeration;
27  import java.util.List;
28  
29  import javax.servlet.http.HttpSession;
30  
31  import org.apache.turbine.Turbine;
32  import org.apache.turbine.TurbineConstants;
33  import org.apache.turbine.modules.Action;
34  import org.apache.turbine.modules.ActionLoader;
35  import org.apache.turbine.services.assemblerbroker.TurbineAssemblerBroker;
36  import org.apache.turbine.services.velocity.VelocityService;
37  import org.apache.turbine.util.RunData;
38  import org.apache.turbine.util.TurbineException;
39  import org.apache.turbine.util.template.TemplateInfo;
40  
41  /**
42   * Handles the Login and Logout actions in the request process
43   * cycle.
44   *
45   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
46   * @author <a href="mailto:dlr@apache.org">Daniel Rall</a>
47   * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
48   * @version $Id: DefaultLoginValve.java 1078552 2011-03-06 19:58:46Z tv $
49   */
50  public class DefaultLoginValve
51      extends AbstractValve
52  {
53      private ActionLoader actionLoader;
54  
55      /**
56       * Here we can setup objects that are thread safe and can be
57       * reused. We setup the session validator and the access
58       * controller.
59       */
60      public DefaultLoginValve()
61          throws Exception
62      {
63          // empty constructor
64      }
65  
66      /**
67       * Initialize this valve for use in a pipeline.
68       *
69       * @see org.apache.turbine.pipeline.AbstractValve#initialize()
70       */
71      @Override
72      public void initialize() throws Exception
73      {
74          super.initialize();
75  
76          this.actionLoader = (ActionLoader)TurbineAssemblerBroker.getLoader(Action.NAME);
77      }
78  
79      /**
80       * @see org.apache.turbine.Valve#invoke(RunData, ValveContext)
81       */
82      @Override
83      public void invoke(PipelineData pipelineData, ValveContext context)
84          throws IOException, TurbineException
85      {
86          try
87          {
88              process(pipelineData);
89          }
90          catch (Exception e)
91          {
92              throw new TurbineException(e);
93          }
94  
95          // Pass control to the next Valve in the Pipeline
96          context.invokeNext(pipelineData);
97      }
98  
99      /**
100      * Handles user sessions, parsing of the action from the query
101      * string, and access control.
102      *
103      * @param data The run-time data.
104      */
105     protected void process(PipelineData pipelineData)
106         throws Exception
107     {
108         RunData data = getRunData(pipelineData);
109         // Special case for login and logout, this must happen before the
110         // session validator is executed in order either to allow a user to
111         // even login, or to ensure that the session validator gets to
112         // mandate its page selection policy for non-logged in users
113         // after the logout has taken place.
114         String actionName = data.getAction();
115         if (data.hasAction() &&
116             actionName.equalsIgnoreCase
117             (Turbine.getConfiguration().getString(TurbineConstants.ACTION_LOGIN_KEY)) ||
118             actionName.equalsIgnoreCase
119             (Turbine.getConfiguration().getString(TurbineConstants.ACTION_LOGOUT_KEY)))
120         {
121             // If a User is logging in, we should refresh the
122             // session here.  Invalidating session and starting a
123             // new session would seem to be a good method, but I
124             // (JDM) could not get this to work well (it always
125             // required the user to login twice).  Maybe related
126             // to JServ?  If we do not clear out the session, it
127             // is possible a new User may accidently (if they
128             // login incorrectly) continue on with information
129             // associated with the previous User.  Currently the
130             // only keys stored in the session are "turbine.user"
131             // and "turbine.acl".
132             if (actionName.equalsIgnoreCase
133                 (Turbine.getConfiguration().getString(TurbineConstants.ACTION_LOGIN_KEY)))
134             {
135                 @SuppressWarnings("unchecked")
136                 Enumeration<String> names = data.getSession().getAttributeNames();
137                 if (names != null)
138                 {
139                     // copy keys into a new list, so we can clear the session
140                     // and not get ConcurrentModificationException
141                     List<String> nameList = new ArrayList<String>();
142                     while (names.hasMoreElements())
143                     {
144                         nameList.add(names.nextElement());
145                     }
146 
147                     HttpSession session = data.getSession();
148                     for (String name : nameList)
149                     {
150                         try
151                         {
152                             session.removeAttribute(name);
153                         }
154                         catch (IllegalStateException invalidatedSession)
155                         {
156                             break;
157                         }
158                     }
159                 }
160             }
161 
162             actionLoader.exec(pipelineData, data.getAction());
163             cleanupTemplateContext(data);
164             data.setAction(null);
165         }
166     }
167     /**
168      * cleans the Velocity Context if available.
169      *
170      * @param data A RunData Object
171      *
172      * @throws Exception A problem while cleaning out the Template Context occured.
173      */
174     private void cleanupTemplateContext(RunData data)
175     throws Exception
176     {
177         // This is Velocity specific and shouldn't be done here.
178         // But this is a band aid until we get real listeners
179         // here.
180         TemplateInfo ti = data.getTemplateInfo();
181         if (ti != null)
182         {
183             ti.removeTemp(VelocityService.CONTEXT);
184         }
185     }
186 }