diff options
Diffstat (limited to 'projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WORequest.java')
| -rw-r--r-- | projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WORequest.java | 586 |
1 files changed, 586 insertions, 0 deletions
diff --git a/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WORequest.java b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WORequest.java new file mode 100644 index 0000000..7d71223 --- /dev/null +++ b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WORequest.java @@ -0,0 +1,586 @@ +/* +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.io.InputStream; +import java.util.Enumeration; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import net.wotonomy.foundation.NSArray; +import net.wotonomy.foundation.NSData; +import net.wotonomy.foundation.NSDictionary; +import net.wotonomy.foundation.NSMutableArray; +import net.wotonomy.foundation.NSMutableData; +import net.wotonomy.foundation.NSMutableDictionary; + +/** +* A pure java implementation of WORequest. +* This implementation is backed by an HttpServletRequest, +* and thus does not support application-specific subclassing. +* Future implementations may remove this limitation. +* +* @author michael@mpowers.net +* @author $Author: cgruber $ +* @version $Revision: 905 $ +*/ +public class WORequest extends WOResponse +{ + HttpServletRequest request; + private WOApplication application; + private NSArray languages; + private String requestHandlerKey; + private String requestHandlerPath; + private String pageName; + private String contextID; + private String senderID; + private String defaultFormValueEncoding; + + /** + * Parameterless constructor which should not be called. + */ + public WORequest () + { + throw new RuntimeException( + "This constructor is not yet supported." ); + } + + /** + * Standard constructor. Method and URL are required. + * HeaderMap is a map of header names to arrays containing + * one or more values. Data is the content of the request. + * UserInfo contains application-defined paramters that get + * passed to all objects involved in dispatching the request. + */ + public WORequest + (String aMethod, String aURL, String aProtocolName, + NSDictionary headerMap, NSData aData, NSDictionary userInfo) + { + throw new RuntimeException( + "This constructor is not yet supported." ); + } + + /** + * The only supported constructor for this implementation. + * This WORequest will wrap the specified servlet request. + */ + public WORequest( HttpServletRequest aRequest, WOApplication anApplication ) + { + request = aRequest; + application = anApplication; + + languages = null; + senderID = null; + pageName = null; + contextID = null; + defaultFormValueEncoding = "ISO8859_1"; + requestHandlerKey = WOApplication.directActionRequestHandlerKey(); + requestHandlerPath = request.getServletPath(); // request.getPathInfo(); + String remainder = requestHandlerPath; + if ( requestHandlerPath == null ) requestHandlerPath = ""; + if ( requestHandlerPath.length() > 0 ) + { + int i; + + // get request handler key + i = requestHandlerPath.indexOf( "/", 1 ); + if ( i != -1 ) + { + requestHandlerKey = requestHandlerPath.substring( 1, i ); + requestHandlerPath = requestHandlerPath.substring( i ); + } + + Enumeration e = requestHandlerPathArray().objectEnumerator(); + // skipping session ID for now + if ( e.hasMoreElements() ) + { + pageName = e.nextElement().toString(); + } + if ( e.hasMoreElements() ) + { + contextID = e.nextElement().toString(); + } + if ( e.hasMoreElements() ) + { + senderID = e.nextElement().toString(); + } + } + } + + /** + * Returns the HTTP method of the request: "GET" or "POST", + * or possibly "PUT". + */ + public String method () + { + return request.getMethod(); + } + + /** + * Returns the Uniform Resource Identifier, which is the part + * of the request URL after the protocol name (after the port + * number) and before the query parameters (before the question mark). + */ + public String uri () + { + return request.getRequestURI(); + } + + /** + * Returns the name of the protocol (presumably HTTP) and the + * version used by the client as sent in the request headers. + */ + public String httpVersion () + { + return request.getProtocol(); + } + + /** + * Returns an array of the header names in this request + * in no particular order. + */ + public NSArray headerKeys () + { + return arrayFromEnumeration( request.getHeaderNames() ); + } + + /** + * Returns an array of the header values for the specified key + * in no particular order. + */ + public NSArray headersForKey (String aString) + { + return arrayFromEnumeration( request.getHeaders( aString ) ); + } + + /** + * Returns one value for the specified header key. + * Provided as a convenience since most headers have + * only one value. Returns null if not found. + */ + public String headerForKey (String aKey) + { + return request.getHeader( aKey ); + } + + /** + * Returns the content of the request, or null if no content. + * The type of the content is determined by the "content-type" header. + * On error, null is returned. + */ + public NSData content () + { + //TODO: This is broken! + NSMutableData data = new NSMutableData(); + try + { + byte[] buf = new byte[ request.getContentLength() ]; + InputStream is = request.getInputStream(); + + // this is so very not efficient + int len; + while ( ( len = is.read( buf ) ) > -1 ) + { + // copies data twice... + data.appendData( new NSData( buf, 0, len ) ); + } + } + catch ( Exception exc ) + { + return null; + } + return data; + } + + /** + * Returns the application-specific userInfo dictionary. + * This implementation returns the servlet attribute map. + */ + public NSDictionary userInfo () + { + //TODO: Test this logic. + Object key, value; + NSMutableDictionary info = new NSMutableDictionary(); + java.util.Enumeration e = request.getAttributeNames(); + while ( e.hasMoreElements() ) + { + key = e.nextElement(); + value = request.getAttribute( e.nextElement().toString() ); + if ( value != null ) + { + info.setObjectForKey( value, key ); + } + } + return info; + } + + /** + * Returns the items in the request handler path parsed + * by the "/" delimiter and put into an array. + */ + public NSArray requestHandlerPathArray () + { + return NSArray.componentsSeparatedByString( requestHandlerPath(), "/" ); + } + + /** + * Returns the client's preferred languages in decreasing + * order of preference. The strings are returned in java + * Locale format, meaning dashes (-) are converted to + * underbars (_): see java.util.Locale.toString(). + */ + public NSArray browserLanguages () + { + if ( languages == null ) + { + languages = arrayFromEnumeration( request.getLocales() ); + } + return languages; + } + + /** + * Returns the portion of the URI specifying the engine within which + * this web application is running. This is important for generating + * URLs to be used in the content of the response. + */ + public String adaptorPrefix () + { + //TODO: Test this logic. + String name = request.getServletPath(); + return name; + +// String uri = request.getRequestURI(); +// int end = uri.indexOf( request.getPathInfo() ); +// return uri.substring( request.getContextPath().length(), end ); + } + + /** + * Returns the application name as specified in the request URI. + * Note that wotonomy web applications do not typically have a .woa + * extension, but the extension will be included for those that do. + */ + public String applicationName () + { + return request.getContextPath(); + } + + /** + * Returns the id of the application instance that is needed to + * service this request. -1 indicates that the request is not + * specific to a particular instance of the application. + * This implementation currently returns -1. + */ + public int applicationNumber () + { + return -1; + } + + /** + * Returns the portion of the URI that specifies which request handler + * should handle the request. + */ + public String requestHandlerKey () + { + return requestHandlerKey; + } + + /** + * Returns the portion of the URI that specifies path information + * for the request, not including the query string. + */ + public String requestHandlerPath () + { + return requestHandlerPath; + } + + /** + * Returns the unique identifier for the sessions associated with + * this request, or null if no session is found. + */ + public String sessionID () + { + HttpSession session = request.getSession( false ); + if ( session == null ) return null; + return session.getId(); + } + + /** + * Returns an array containing all the form keys in the request. + */ + public NSArray formValueKeys () + { + return arrayFromEnumeration( request.getParameterNames() ); + } + + /** + * Returns an array of the values for the specified key in + * no particular order. + */ + public NSArray formValuesForKey (String aKey) + { + NSMutableArray result = new NSMutableArray(); + String[] values = request.getParameterValues( aKey ); + if ( values != null ) + { + for ( int i = 0; i < values.length; i++ ) + { + result.addObject( values[i] ); + } + } + return result; + } + + /** + * Returns one value for the specified key. + * Provided as a convenience since most keys have + * only one value. Returns null if not found. + */ + public Object formValueForKey (String aKey) + { + return request.getParameter( aKey ); + } + + /** + * Returns the value for the specified key, as a String. + */ + public String stringFormValueForKey(String key) { + Object x = formValueForKey(key); + if (x != null) + return x.toString(); + return null; + } + + /** + * Returns a dictionary containing all the key-value + * mappings in the request. + */ + public NSDictionary formValues () + { + NSMutableDictionary result = new NSMutableDictionary (); + java.util.Enumeration e = request.getParameterNames(); + String key; + while ( e.hasMoreElements() ) + { + key = e.nextElement().toString(); + result.setObjectForKey( formValuesForKey( key ), key ); + } + return result; + } + + /** + * Returns whether the request is from a java-based client component. + * This implementation returns false. + */ + public boolean isFromClientComponent () + { + return false; + } + + /** + * Returns an array of cookie values for the specified key in + * no particular order. + */ + public NSArray cookieValuesForKey (String aKey) + { + // TODO: Test this logic. + NSMutableArray result = new NSMutableArray(); + Cookie[] cookies = request.getCookies(); + if ( cookies == null ) return result; + + for ( int i = 0; i < cookies.length; i++ ) + { + if ( cookies[i].getName().equals( aKey ) ) + { + result.addObject( cookies[i].getValue() ); + } + } + + return result; + } + + /** + * Returns one value for the specified cookie key. + * Provided as a convenience since most cookies have + * only one value. Returns null if not found. + */ + public String cookieValueForKey (String aKey) + { + // TODO: Test this logic. + Cookie[] cookies = request.getCookies(); + if ( cookies == null ) return null; + + for ( int i = 0; i < cookies.length; i++ ) + { + if ( cookies[i].getName().equals( aKey ) ) + { + return cookies[i].getValue(); + } + } + + return null; + } + + /** + * Returns a dictionary of cookie key-value mappings. + */ + public NSDictionary cookieValues () + { + // TODO: Test this logic. + NSMutableDictionary result = new NSMutableDictionary(); + Cookie[] cookies = request.getCookies(); + if ( cookies == null ) return result; + + NSMutableArray value; + for ( int i = 0; i < cookies.length; i++ ) + { + value = (NSMutableArray) result.objectForKey( + cookies[i].getName() ); + if ( value == null ) + { + value = new NSMutableArray(); + result.setObjectForKey( + cookies[i].getValue(), cookies[i].getName() ); + } + value.addObject( cookies[i].getValue() ); + } + + return result; + } + + /** + * Sets the default character encoding. + */ + public void setDefaultFormValueEncoding (String encoding) + { + defaultFormValueEncoding = encoding; + } + + /** + * Returns the default form value encoding ("ISO8859_1"). + */ + public String defaultFormValueEncoding () + { + return defaultFormValueEncoding; + } + + /** + * Sets whether the appropriate encoding scheme for decoding + * the form values will be automatically determined. + */ + public void setFormValueEncodingDetectionEnabled (boolean enabled) + { + throw new RuntimeException( "Not yet implemented." ); + } + + /** + * Gets whether the appropriate encoding scheme for decoding + * the form values is currently automatically determined. + */ + public boolean isFormValueEncodingDetectionEnabled () + { + throw new RuntimeException( "Not yet implemented." ); + } + + /** + * Gets the current method used for decoding form values. + */ + public int formValueEncoding () + { + throw new RuntimeException( "Not yet implemented." ); + } + + /** + * Returns the host name of the server that is the target of this request. + * NOTE: This method is not published in the WORequest specification. + */ + String applicationHost () + { + // FIXME: this should call WOApplication.hostname(); + return request.getServerName(); + } + + /** + * Returns the port of the server that is the target of this request. + * NOTE: This method is not published in the WORequest specification. + */ + int port() + { + // FIXME: this should call WOApplication.port(); + return request.getServerPort(); + } + + /** + * Returns the backing HttpServletRequest. + */ + HttpServletRequest servletRequest () + { + return request; + } + + /** + * Returns the application that was the target of this request. + * This method is not published in the WORequest specification. + */ + WOApplication application () + { + return application; + } + + /** + * This method is not published in the WORequest specification. + * This sender id from the URI, which is the id of the element + * that generated this request. + */ + String senderID () + { + return senderID; + } + + /** + * This method is not published in the WORequest specification. + * This returns the context id from the URI. + */ + String contextID () + { + return contextID; + } + + /** + * This method is not published in the WORequest specification. + */ + String pageName () + { + return pageName; + } + + /** + * Convenience method to populate an NSArray from an Enumeration. + */ + private static NSArray arrayFromEnumeration( java.util.Enumeration e ) + { + NSMutableArray result = new NSMutableArray(); + while ( e.hasMoreElements() ) + { + result.addObject( e.nextElement() ); + } + return result; + } +} |
