View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Blacksmith, Inc.
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.web;
20  
21  import net.wotonomy.foundation.NSArray;
22  
23  /***
24  * An implementation of WORequestHandler that dispatches
25  * DirectActions. <br><br>
26  *
27  * See WODirectAction for the rules for parsing a request.
28  * In short, className defaults to "DirectAction", and the
29  * action defaults to "default".  The action class is expected
30  * to have a constructor that takes a WORequest parameter.
31  *
32  * @author michael@mpowers.net
33  * @author $Author: cgruber $
34  * @version $Revision: 905 $
35  */
36  public class WODirectActionRequestHandler
37  	extends WORequestHandler
38  {
39      public WOResponse handleRequest (WORequest aRequest)
40      {
41          WOResponse response = null;
42          
43          // no concurrent access is allowed to a user's session:
44          // a user/browser/machine with multiple requests will have to wait.
45          // NOTE: this forces a session creation for any direct action (!)
46          synchronized ( aRequest.request.getSession() )
47          {
48              WOApplication application = aRequest.application();
49              WOContext context = WOContext.contextWithRequest( aRequest );
50              
51              String className = "DirectAction";
52              String actionName = "default";
53              NSArray path = aRequest.requestHandlerPathArray();
54              if ( path.count() > 0 )
55              {
56                  className = path.objectAtIndex( 0 ).toString();
57                  if ( path.count() > 1 )
58                  {
59                      actionName = path.objectAtIndex( path.count() - 1 ).toString();
60                  }
61                  if ( path.count() > 2 )
62                  {
63                      for ( int i = 1; i < path.count()-1; i++ )
64                      {
65                          className = className + "." +
66                              path.objectAtIndex( i ).toString();
67                      }
68                  }
69              }
70      
71              //FIXME: sessions are supposed to be lazily created for direct actions
72              
73              WOSession session = null;
74              
75              String sessionID = aRequest.sessionID();
76              if ( sessionID != null )
77              {
78                  session = application.restoreSessionWithID( sessionID, context );
79              }
80      
81              if ( session == null )
82              {
83                  session = application.createSessionForRequest( aRequest );
84                  if ( session == null )
85                  {
86                      response = application.handleSessionCreationErrorInContext( context );
87                  }
88                  else
89                  {
90                      session.setContext( context );
91                  }
92              }
93              
94              context.setSession( session );
95              
96              application.awake();
97              session.awake();
98              
99              try
100             {
101                 
102                 if ( response == null )
103                 {
104                     Class c = null;
105                     c = application.getLocalClass( className );
106                     if ( ( c == null ) && ( path.count() == 1 ) )
107                     {
108                         actionName = className;
109                         className = "DirectAction";
110                         c = application.getLocalClass( className );
111                     }
112                     if ( c == null )
113                     {
114                         throw new RuntimeException(
115                             "Could not find class named \"" + className
116                             + "\": " );
117                     }
118                     java.lang.reflect.Constructor ctor =
119                         c.getConstructor( new Class[] { WORequest.class } );
120         
121                     WODirectAction action = (WODirectAction)
122                         ctor.newInstance( new Object[] { aRequest } );
123                     action.context = context; //HACK: how else can action call pageWithName?
124                     
125                     WOActionResults result = action.performActionNamed( actionName );
126                     if ( result instanceof WOComponent ) 
127                     {
128                         //HACK: I'm not sure where this should have gone: seems hackish here.
129                         context.pushElement( (WOComponent) result );
130                         ((WOComponent)result).ensureAwakeInContext( context );
131                         //context.popElement();
132                     }
133                     response = result.generateResponse(); // calls session.savePage (?)
134                     if ( result instanceof WOComponent ) 
135                     {
136                         //HACK: I'm not sure where this should have gone: seems hackish here.
137                         ((WOComponent)result).sleep();
138                     }
139                 }
140             }
141             catch ( NoSuchMethodException exc )
142             {
143                 WOResponse error = new WOResponse();
144                 exc.printStackTrace();
145                 error.setStatus( 404 ); // not found
146                 error.appendContentString(
147                     "Could not find request constructor for class named \""
148                         + className + "\": " );
149                 response = error;
150             }
151             catch ( Exception exc )
152             {
153                 WOResponse error = new WOResponse();
154                 error.setStatus( 500 ); // error
155                 if ( exc.getMessage() != null )
156                 {
157                     error.appendContentString( exc.getMessage() );
158                     exc.printStackTrace();
159                 }
160                 else
161                 {
162                     error.appendContentString( exc.toString() );
163                     exc.printStackTrace();
164                 }
165                 response = error;
166             }
167             
168             session.sleep();
169             session.setContext( null );
170             application.saveSessionForContext( context );
171             application.sleep();
172         }
173         return response;
174     }
175     
176 }
177 
178 /*
179  * $Log$
180  * Revision 1.2  2006/02/19 01:44:02  cgruber
181  * Add xmlrpc files
182  * Remove jclark and replace with dom4j and javax.xml.sax stuff
183  * Re-work dependencies and imports so it all compiles.
184  *
185  * Revision 1.1  2006/02/16 13:22:22  cgruber
186  * Check in all sources in eclipse-friendly maven-enabled packages.
187  *
188  * Revision 1.10  2003/03/28 17:26:18  mpowers
189  * Implemented package support: Applications can now live in packages.
190  * Better support for locating package local classes.
191  *
192  * Revision 1.9  2003/01/19 22:33:26  mpowers
193  * Fixed problems with classpath and dynamic class loading.
194  * Dynamic elements now pass on ensureAwakeInContext.
195  * Parser how handles <standalone/> tags.
196  *
197  * Revision 1.8  2003/01/17 20:34:57  mpowers
198  * Better handling for components and parents in the context's element stack.
199  *
200  * Revision 1.7  2003/01/15 19:50:49  mpowers
201  * Fixed issues with WOSession and Serializable.
202  * Can now persist sessions between classloaders (hot swap of class impls).
203  *
204  * Revision 1.5  2003/01/13 22:25:00  mpowers
205  * Request-response cycle is working with session and page persistence.
206  *
207  * Revision 1.4  2003/01/09 21:16:49  mpowers
208  * Bringing request-response cycle more into conformance.
209  *
210  * Revision 1.2  2002/12/17 14:57:44  mpowers
211  * Minor corrections to WORequests's parsing, and updated javadocs.
212  *
213  * Revision 1.1.1.1  2000/12/21 15:53:19  mpowers
214  * Contributing wotonomy.
215  *
216  * Revision 1.2  2000/12/20 16:25:50  michael
217  * Added log to all files.
218  *
219  *
220  */
221