From aedc34d55462a75e329bbf342251ff6504cd117e Mon Sep 17 00:00:00 2001 From: Benjamin Culkin Date: Sun, 19 May 2024 17:56:33 -0400 Subject: Initial import from SVN --- .../src/main/java/net/wotonomy/web/WOContext.java | 572 +++++++++++++++++++++ 1 file changed, 572 insertions(+) create mode 100644 projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java (limited to 'projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java') diff --git a/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java new file mode 100644 index 0000000..4f774e6 --- /dev/null +++ b/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java @@ -0,0 +1,572 @@ +/* +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.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** +* A pure java implementation of WOContext. +* +* @author michael@mpowers.net +* @author $Author: cgruber $ +* @version $Revision: 905 $ +*/ +public class WOContext +{ + private WOSession session; + private WORequest request; + private WOResponse response; + private List elementStack; + private boolean isInForm; + private boolean isDistributionEnabled; + private static final String EMPTY = ""; + private static final String SEP = "."; + private static final String ZERO = "0"; + private static final String HTTP = "http://"; + private static final String HTTPS = "https://"; + + // package access + WOComponent page; + WOComponent component; + StringBuffer elementID; + + private static volatile int contextCounter = 0; + private String contextID; + + /** + * Default constructor performs necessary initialization. + * Subclassers should override the static factory method below. + */ + public WOContext () + { + contextID = null; + elementID = new StringBuffer(); + elementStack = new LinkedList(); + } + + /** + * Preferred constructor performs necessary initialization. + * Subclassers should override this method. + */ + public WOContext (WORequest aRequest) + { + this(); + request = aRequest; + response = new WOResponse(); + } + + /** + * Simply calls the preferred constructor. + * Included for compatibility. + */ + public static WOContext contextWithRequest (WORequest aRequest) + { + String id = Integer.toString( contextCounter++ ); + WOContext result = new WOContext( aRequest ); + result.contextID = id; + return result; + } + + /** + * Returns the context id. + */ + public String contextID () + { + return contextID; + } + + /** + * Returns the sender id, or null if it doesn't exist. + */ + public String senderID () + { + return request.senderID(); + } + + /** + * Returns the element id, or null if it doesn't exist. + */ + public String elementID () + { + return elementID.toString(); + } + + /** + * Returns this context's application, or null if it doesn't exist. + */ + public WOApplication application () + { + return request.application(); + } + + /** + * Returns whether a session has been created for the associated request. + */ + public boolean hasSession () + { + return ( session != null ); + } + + /** + * Returns this context's session, creating one if it doesn't exist. + */ + public WOSession session () + { + if ( session == null ) + { + // so far we can't figure out how the direct action handler can avoid creating a session + throw new RuntimeException( "WOContext.session: Lazy instantiation not yet implemented." ); +/* + session = application().restoreSessionWithID( + request.sessionID(), this ); + if ( session == null ) + { + session = application().createSessionForRequest( request ); + session.setContext( this ); + } +*/ + } + return session; + } + + /** + * Package access only. + */ + void setSession( WOSession aSession ) + { + session = aSession; + } + + /** + * Returns this context's request. + */ + public WORequest request () + { + return request; + } + + /** + * Returns this context's response. + */ + public WOResponse response () + { + return response; + } + + /** + * Returns the current page. + */ + public WOComponent page () + { + return (WOComponent) elementStack.get( elementStack.size()-1 ); + } + + /** + * Returns the current component. + */ + public WOComponent component () + { + Object o; + Iterator i = elementStack.iterator(); + while ( i.hasNext() ) + { + o = i.next(); + if ( o instanceof WOComponent ) return (WOComponent) o; + } + return null; + } + + /** + * Returns the current component's parent. + */ + WOComponent parent () + { + Object o; + Iterator i = elementStack.iterator(); + if ( i.hasNext() ) + { + // skip current component + o = i.next(); + } + while ( i.hasNext() ) + { + o = i.next(); + if ( o instanceof WOComponent ) + { + return (WOComponent) o; + } + } + return null; + } + + /** + * Pushes an element onto the stack. + * Package access only. + */ + void pushElement( WOElement aComponent ) + { + elementStack.add( 0, aComponent ); + } + + /** + * Pops an element off the stack. + * Package access only. + */ + WOElement popElement() + { + return (WOElement) elementStack.remove(0); + } + + /** + * Returns whether the current context is in a form. + */ + public boolean isInForm () + { + return isInForm; + } + + /** + * Sets whether the current context is in a WOForm. + */ + public void setInForm (boolean inForm) + { + isInForm = inForm; + } + + /** + * Appends the specified string to the end of the element id. + * For example, if the element id is "0.1", sending "Test" + * changes the element id to "0.1.Test". + */ + public void appendElementIDComponent (String aString) + { + if ( elementID.length() > 0 ) + { + elementID.append( SEP ); + } + elementID.append( aString ); + } + + /** + * Appends a zero to the element id to represent the first + * new child component. For example, if the element id is "0.1", + * calling this changes the element id to "0.1.0". + */ + public void appendZeroElementIDComponent () + { + if ( elementID.length() > 0 ) + { + elementID.append( SEP ); + } + elementID.append( ZERO ); + } + + /** + * Increments the last component of the element id. + * For example, if the element id is "0.1", calling this + * changes the element id to "0.2". + */ + public void incrementLastElementIDComponent () + { + String last; + String id = elementID.toString(); + int index = id.lastIndexOf( SEP ); + if ( index == -1 ) + { + last = id; + } + else + { + last = id.substring( index + 1 ); + } + + deleteLastElementIDComponent(); + + try + { + appendElementIDComponent( + Integer.toString( Integer.parseInt( last ) + 1 ) ); + } + catch ( Exception exc ) + { + System.err.println( "Error parsing id: " + last ); + appendZeroElementIDComponent(); + } + //System.out.println( "WOContext: " + elementID ); + } + + /** + * Deletes the last component of the element id. + * For example, if the element id is "0.1", callling this + * changes the element id to "0". + */ + public void deleteLastElementIDComponent () + { + int index = elementID.toString().lastIndexOf( SEP ); + if ( index == -1 ) + { + elementID.setLength( 0 ); + } + else + { + elementID.setLength( index ); + } + } + + /** + * Deletes all components of the element id. + * This makes the element id an empty string. + */ + public void deleteAllElementIDComponents () + { + elementID.setLength( 0 ); + } + + /** + * Returns a URL for the named action with query parameters + * as specified by the dictionary. + */ + public String directActionURLForActionNamed ( + String anActionName, Map aQueryDict) + { + StringBuffer query = new StringBuffer(); + + try + { + String key; + Iterator i = aQueryDict.keySet().iterator(); + while ( i.hasNext() ) + { + key = i.next().toString(); + query.append( URI.encode( key, + URI.allowed_within_query ) ); + query.append( '=' ); + query.append( URI.encode( aQueryDict.get( key ).toString(), + URI.allowed_within_query ) ); + if ( i.hasNext() ) + { + query.append( '&' ); + } + } + } + catch ( IOException exc ) + { + // report error + System.err.println( + "directActionURLForActionNamed: " + anActionName + " : " + aQueryDict ); + System.err.println( exc ); + + // delete query string + query = new StringBuffer(); + } + + return urlWithRequestHandlerKey( + WOApplication.directActionRequestHandlerKey(), + anActionName, query.toString() ); + } + + /** + * Returns the complete URL for the current component action. + */ + public String componentActionURL () + { + StringBuffer buffer = new StringBuffer(); + buffer.append( request().applicationName() ); + buffer.append( '/' ); + buffer.append( WOApplication.application().componentRequestHandlerKey() ); + buffer.append( '/' ); + buffer.append( page().name() ); + buffer.append( '/' ); + buffer.append( contextID ); + buffer.append( '/' ); + buffer.append( elementID ); + return buffer.toString(); + } + + /** + * Returns a URL relative to the servlet for the specified + * request handler, action, and query string. + */ + public String urlWithRequestHandlerKey ( + String aRequestHandlerKey, String aPath, String aQueryString) + { + StringBuffer buffer = new StringBuffer(); + buffer.append( request().applicationName() ); + buffer.append( '/' ); + buffer.append( aRequestHandlerKey ); + buffer.append( '/' ); + buffer.append( aPath ); + if ( aQueryString != null && aQueryString.trim().length() > 0 ) + { + buffer.append( '?' ); + buffer.append( aQueryString ); + } + return buffer.toString(); + } + + /** + * Returns the complete URL for the specified request handler, + * path, and query string. isSecure determines the protocol: + * http or https. port is appended to the protocol, if zero, + * the port is omitted from the URL. + */ + public String completeURLWithRequestHandlerKey ( + String aRequestHandlerKey, String aPath, String aQueryString, + boolean isSecure, int port) + { + StringBuffer buffer = new StringBuffer(); + + if ( isSecure ) + { + buffer.append( HTTPS ); + } + else + { + buffer.append( HTTP ); + } + + buffer.append( request.applicationHost() ); + + if ( port != 0 && port != 80 ) + { + buffer.append( ':' ); + buffer.append( Integer.toString( port ) ); + } + + buffer.append( urlWithRequestHandlerKey( + aRequestHandlerKey, aPath, aQueryString ) ); + + return buffer.toString(); + } + + /** + * Sets whether distribution is enabled. + */ + public void setDistributionEnabled (boolean distributionEnabled) + { + isDistributionEnabled = distributionEnabled; + } + + /** + * Returns whether distribution is enabled. + */ + public boolean isDistributionEnabled () + { + return isDistributionEnabled; + } + + /** + * This method is not included in the WOContext specification. + * This implementation returns "" since only cookie ids are + * currently supported. + */ + String urlSessionPrefix () + { + return EMPTY; // "/" + sessionid; + } + + /** + * Returns the relative URL for the current page. + */ + String url () + { + throw new RuntimeException( "Not implemented yet." ); + } + + public String toString() + { + return "[WOContext@"+Integer.toHexString(System.identityHashCode(this)) + +":id=" + contextID +":page=" + page + ":component=" + component + ":element=" + elementID + "]"; + } +} + +/* + * $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.19 2003/08/07 00:15:15 chochos + * general cleanup (mostly removing unused imports) + * + * Revision 1.18 2003/02/21 16:40:23 mpowers + * Now reading port and smtp host from system properties. + * Implemented WOApplication.main. + * + * Revision 1.17 2003/01/24 20:12:54 mpowers + * Better parent determination. + * + * Revision 1.16 2003/01/21 22:27:02 mpowers + * Corrected context id usage. + * Implemented backtracking. + * + * Revision 1.15 2003/01/17 20:58:19 mpowers + * Fixed up WOHyperlink. + * + * Revision 1.14 2003/01/17 20:34:57 mpowers + * Better handling for components and parents in the context's element stack. + * + * Revision 1.13 2003/01/14 19:48:36 mpowers + * - fixes to property synchronization + * - forms now pass takeValuesFromRequest to children + * - fixes to action invocation + * - now supporting multipleSubmit in forms + * + * Revision 1.12 2003/01/13 22:24:44 mpowers + * Request-response cycle is working with session and page persistence. + * + * Revision 1.11 2003/01/10 20:17:41 mpowers + * Component action urls are now working. + * + * Revision 1.8 2003/01/09 21:16:48 mpowers + * Bringing request-response cycle more into conformance. + * + * Revision 1.7 2003/01/09 16:13:59 mpowers + * Implemented WOComponentRequestHandler: + * Bringing the request-response cycle more into conformance. + * + * Revision 1.4 2002/12/20 22:56:33 mpowers + * Reimplemented the template parsing again. + * Nested components are now correctly parsed. + * ElementID numbering is now working. + * + * Revision 1.3 2002/12/18 14:12:38 mpowers + * Support for differentiated request handlers. + * Support url generation for WOContext and WORequest. + * + * Revision 1.2 2002/12/17 14:57:42 mpowers + * Minor corrections to WORequests's parsing, and updated javadocs. + * + * Revision 1.1.1.1 2000/12/21 15:53:04 mpowers + * Contributing wotonomy. + * + * Revision 1.3 2000/12/20 16:25:49 michael + * Added log to all files. + * + * + */ + -- cgit v1.2.3