diff options
Diffstat (limited to 'projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WODirectAction.java')
| -rw-r--r-- | projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WODirectAction.java | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WODirectAction.java b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WODirectAction.java new file mode 100644 index 0000000..09d0131 --- /dev/null +++ b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WODirectAction.java @@ -0,0 +1,317 @@ +/* +Wotonomy: OpenStep design patterns for pure Java applications. +Copyright (C) 2000 Blacksmith, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, see http://www.gnu.org +*/ + +package net.wotonomy.web; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import javax.servlet.http.HttpSession; + +import net.wotonomy.foundation.NSArray; +import net.wotonomy.foundation.NSSelector; +import net.wotonomy.foundation.internal.Introspector; +import net.wotonomy.foundation.internal.ValueConverter; + +/** +* A pure java implementation of WODirectAction. +* This class provides a number of services to subclasses, +* including access to the query parameters, the request, +* the session, and logging and debugging facilities. +* A new instance of the class is created and then destroyed +* for every request-response cycle.<br><br> +* +* Subclass this to implement direct actions for your +* application. Subclasses would typically override the +* constructor to initialize state based on the request, +* and then provide additional methods that would be invoked +* based on the value at the end of the URI. <br><br> +* +* Example: "http://www/MyApp.woa/MyActions/search" would call +* the method named "searchAction" on the DirectAction subclass +* named "MyActions". If the subclass name is omitted, a subclass +* named "DirectAction" is assumed to exist within the application. +* +* @author michael@mpowers.net +* @author $Author: cgruber $ +* @version $Revision: 905 $ +*/ +public class WODirectAction +{ + private WORequest request; + WOContext context; + + /** + * Default constructor. This is called implicitly by + * subclasses in all cases. Package access only. + */ + WODirectAction () + { + + } + + /** + * Request constructor. This is the constructor used + * to create an action in response to a user request. + * Override to perform any necessary initialization in + * your subclass. + */ + public WODirectAction (WORequest aRequest) + { + this(); + request = aRequest; + } + + /** + * Returns the response from the component named "Main". + */ + public WOActionResults defaultAction() + { + return pageWithName("Main").generateResponse(); + } + + /** + * Returns the WORequest object for the current request. + */ + public WORequest request () + { + return request; + } + + /** + * Returns the existing session, or null if no session exists. + */ + public WOSession existingSession () + { + //FIXME: this is incorrect + HttpSession session = request.servletRequest().getSession(); + if ( session == null ) return null; + WOSession wosession = new WOSession(); + wosession.setServletSession( session ); + return wosession; + } + + /** + * Returns the existing session if it exists. If no session + * exists, returns a newly created session. Note that if the + * user client does not support session ids/cookies, this will + * create a new session with each request. + */ + public WOSession session () + { + //FIXME: this is incorrect + WOSession wosession = new WOSession(); + wosession.setServletSession( + request.servletRequest().getSession( true ) ); + return wosession; + } + + /** + * Returns the named WOComponent. + */ + public WOComponent pageWithName (String aString) + { + return request.application().pageWithName( aString, context ); + } + + /** + * Appends "Action" to the specified string and tries to invoke + * method with that name and no arguments. Returns null if + * the method does not exist. If anAction is null, "defaultAction" + * will be assumed. + */ + public WOActionResults performActionNamed (String anAction) + { + if ( anAction == null ) anAction = "default"; + try + { + NSSelector sel = new NSSelector( anAction+"Action" ); + return (WOActionResults) sel.invoke( this ); + } + catch ( NoSuchMethodException exc ) + { + // returns below + } + catch ( InvocationTargetException exc ) + { + Throwable e = exc.getTargetException(); + exc.printStackTrace(); + throw new RuntimeException( e.toString() ); + } + catch ( Exception exc ) + { + exc.printStackTrace(); + throw new RuntimeException( exc.toString() ); + } + WOResponse error = new WOResponse(); + error.setStatus( 404 ); // not found + error.appendContentString( + "Could not find method named \"" + anAction + "Action\"." ); + return error; + } + + /** + * Assigns the arrays of form values for the specified keys + * to properties on this object with matching names whose type + * is NSArray or is convertable from a Collection. + */ + public void takeFormValueArraysForKeyArray (NSArray anArray) + { + if ( anArray == null ) return; + + Method m; + Object key; + Object value; + java.util.Enumeration e = anArray.objectEnumerator(); + while ( e.hasMoreElements() ) + { + key = e.nextElement(); + value = request.formValuesForKey( key.toString() ); + try + { + // obtain setter method for this class + m = Introspector.getPropertyWriteMethod( + this.getClass(), key.toString(), + new Class[] { Introspector.WILD } ); + if ( m != null ) + { + // if value isn't null, try to convert it to type + if ( value != null ) + { + Class[] paramTypes = m.getParameterTypes(); + if ( ! paramTypes[0].isAssignableFrom( + value.getClass() ) ) + { + //TODO: find a constructor whose parameter + // is assignable from value.getClass() + // and instantiate it in the place of value. + } + } + // set property to value + m.invoke( this, new Object[] { value } ); + } + } + catch ( Exception exc ) + { + // show error and continue + debugString( "WODirectAction.takeFormValuesForKeyArray: " + exc ); + } + } + + } + + /** + * Assigns the form values for the specified keys to properties + * on this object with matching names. + */ + public void takeFormValuesForKeyArray (NSArray anArray) + { + if ( anArray == null ) return; + + Method m; + Object key; + Object value; + java.util.Enumeration e = anArray.objectEnumerator(); + while ( e.hasMoreElements() ) + { + key = e.nextElement(); + value = request.formValueForKey( key.toString() ); + try + { + // obtain setter method for this class + m = Introspector.getPropertyWriteMethod( + this.getClass(), key.toString(), + new Class[] { Introspector.WILD } ); + if ( m != null ) + { + // if value isn't null, try to convert it to type + if ( value != null ) + { + Class[] paramTypes = m.getParameterTypes(); + Object convertedValue = + ValueConverter.convertObjectToClass( + value, paramTypes[0] ); + if ( convertedValue != null ) + { + value = convertedValue; + } + } + // set property to value + m.invoke( this, new Object[] { value } ); + } + } + catch ( Exception exc ) + { + // show error and continue + debugString( "WODirectAction.takeFormValuesForKeyArray: " + exc ); + } + } + + } + + /** + * Writes a message to the standard error stream. + */ + public static void logString (String aString) + { + System.err.println( aString ); + } + + /** + * Writes a message to the standard error stream + * if debugging is activated. + */ + public static void debugString (String aString) + { + // TODO: Check to see if debugging is enabled. + System.err.println( aString ); + } +} + +/* + * $Log$ + * Revision 1.2 2006/02/19 01:44:02 cgruber + * Add xmlrpc files + * Remove jclark and replace with dom4j and javax.xml.sax stuff + * Re-work dependencies and imports so it all compiles. + * + * Revision 1.1 2006/02/16 13:22:22 cgruber + * Check in all sources in eclipse-friendly maven-enabled packages. + * + * Revision 1.5 2003/01/13 22:24:51 mpowers + * Request-response cycle is working with session and page persistence. + * + * Revision 1.4 2003/01/09 21:16:48 mpowers + * Bringing request-response cycle more into conformance. + * + * Revision 1.3 2003/01/07 15:58:11 mpowers + * Implementing the request-response cycle. + * WOSession refactored to support distribution. + * + * Revision 1.2 2002/12/17 14:57:43 mpowers + * Minor corrections to WORequests's parsing, and updated javadocs. + * + * Revision 1.1.1.1 2000/12/21 15:53:18 mpowers + * Contributing wotonomy. + * + * Revision 1.2 2000/12/20 16:25:50 michael + * Added log to all files. + * + * + */ + |
