| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
| WODirectActionRequestHandler |
|
| 17.0;17 |
| 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 | 0 | public class WODirectActionRequestHandler |
| 37 | extends WORequestHandler |
|
| 38 | { |
|
| 39 | public WOResponse handleRequest (WORequest aRequest) |
|
| 40 | { |
|
| 41 | 0 | 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 | 0 | synchronized ( aRequest.request.getSession() ) |
| 47 | { |
|
| 48 | 0 | WOApplication application = aRequest.application(); |
| 49 | 0 | WOContext context = WOContext.contextWithRequest( aRequest ); |
| 50 | ||
| 51 | 0 | String className = "DirectAction"; |
| 52 | 0 | String actionName = "default"; |
| 53 | 0 | NSArray path = aRequest.requestHandlerPathArray(); |
| 54 | 0 | if ( path.count() > 0 ) |
| 55 | { |
|
| 56 | 0 | className = path.objectAtIndex( 0 ).toString(); |
| 57 | 0 | if ( path.count() > 1 ) |
| 58 | { |
|
| 59 | 0 | actionName = path.objectAtIndex( path.count() - 1 ).toString(); |
| 60 | } |
|
| 61 | 0 | if ( path.count() > 2 ) |
| 62 | { |
|
| 63 | 0 | for ( int i = 1; i < path.count()-1; i++ ) |
| 64 | { |
|
| 65 | 0 | className = className + "." + |
| 66 | 0 | path.objectAtIndex( i ).toString(); |
| 67 | } |
|
| 68 | } |
|
| 69 | } |
|
| 70 | ||
| 71 | //FIXME: sessions are supposed to be lazily created for direct actions |
|
| 72 | ||
| 73 | 0 | WOSession session = null; |
| 74 | ||
| 75 | 0 | String sessionID = aRequest.sessionID(); |
| 76 | 0 | if ( sessionID != null ) |
| 77 | { |
|
| 78 | 0 | session = application.restoreSessionWithID( sessionID, context ); |
| 79 | } |
|
| 80 | ||
| 81 | 0 | if ( session == null ) |
| 82 | { |
|
| 83 | 0 | session = application.createSessionForRequest( aRequest ); |
| 84 | 0 | if ( session == null ) |
| 85 | { |
|
| 86 | 0 | response = application.handleSessionCreationErrorInContext( context ); |
| 87 | 0 | } |
| 88 | else |
|
| 89 | { |
|
| 90 | 0 | session.setContext( context ); |
| 91 | } |
|
| 92 | } |
|
| 93 | ||
| 94 | 0 | context.setSession( session ); |
| 95 | ||
| 96 | 0 | application.awake(); |
| 97 | 0 | session.awake(); |
| 98 | ||
| 99 | try |
|
| 100 | { |
|
| 101 | ||
| 102 | 0 | if ( response == null ) |
| 103 | { |
|
| 104 | 0 | Class c = null; |
| 105 | 0 | c = application.getLocalClass( className ); |
| 106 | 0 | if ( ( c == null ) && ( path.count() == 1 ) ) |
| 107 | { |
|
| 108 | 0 | actionName = className; |
| 109 | 0 | className = "DirectAction"; |
| 110 | 0 | c = application.getLocalClass( className ); |
| 111 | } |
|
| 112 | 0 | if ( c == null ) |
| 113 | { |
|
| 114 | 0 | throw new RuntimeException( |
| 115 | 0 | "Could not find class named \"" + className |
| 116 | 0 | + "\": " ); |
| 117 | } |
|
| 118 | 0 | java.lang.reflect.Constructor ctor = |
| 119 | 0 | c.getConstructor( new Class[] { WORequest.class } ); |
| 120 | ||
| 121 | 0 | WODirectAction action = (WODirectAction) |
| 122 | 0 | ctor.newInstance( new Object[] { aRequest } ); |
| 123 | 0 | action.context = context; //HACK: how else can action call pageWithName? |
| 124 | ||
| 125 | 0 | WOActionResults result = action.performActionNamed( actionName ); |
| 126 | 0 | if ( result instanceof WOComponent ) |
| 127 | { |
|
| 128 | //HACK: I'm not sure where this should have gone: seems hackish here. |
|
| 129 | 0 | context.pushElement( (WOComponent) result ); |
| 130 | 0 | ((WOComponent)result).ensureAwakeInContext( context ); |
| 131 | //context.popElement(); |
|
| 132 | } |
|
| 133 | 0 | response = result.generateResponse(); // calls session.savePage (?) |
| 134 | 0 | if ( result instanceof WOComponent ) |
| 135 | { |
|
| 136 | //HACK: I'm not sure where this should have gone: seems hackish here. |
|
| 137 | 0 | ((WOComponent)result).sleep(); |
| 138 | } |
|
| 139 | } |
|
| 140 | } |
|
| 141 | 0 | catch ( NoSuchMethodException exc ) |
| 142 | { |
|
| 143 | 0 | WOResponse error = new WOResponse(); |
| 144 | 0 | exc.printStackTrace(); |
| 145 | 0 | error.setStatus( 404 ); // not found |
| 146 | 0 | error.appendContentString( |
| 147 | 0 | "Could not find request constructor for class named \"" |
| 148 | 0 | + className + "\": " ); |
| 149 | 0 | response = error; |
| 150 | } |
|
| 151 | 0 | catch ( Exception exc ) |
| 152 | { |
|
| 153 | 0 | WOResponse error = new WOResponse(); |
| 154 | 0 | error.setStatus( 500 ); // error |
| 155 | 0 | if ( exc.getMessage() != null ) |
| 156 | { |
|
| 157 | 0 | error.appendContentString( exc.getMessage() ); |
| 158 | 0 | exc.printStackTrace(); |
| 159 | 0 | } |
| 160 | else |
|
| 161 | { |
|
| 162 | 0 | error.appendContentString( exc.toString() ); |
| 163 | 0 | exc.printStackTrace(); |
| 164 | } |
|
| 165 | 0 | response = error; |
| 166 | 0 | } |
| 167 | ||
| 168 | 0 | session.sleep(); |
| 169 | 0 | session.setContext( null ); |
| 170 | 0 | application.saveSessionForContext( context ); |
| 171 | 0 | application.sleep(); |
| 172 | 0 | } |
| 173 | 0 | 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 |