summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java')
-rw-r--r--projects/net.wotonomy.web/src/main/java/net/wotonomy/web/WOContext.java572
1 files changed, 572 insertions, 0 deletions
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.
+ *
+ *
+ */
+