You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by hu...@apache.org on 2005/06/15 18:23:55 UTC

svn commit: r190773 - in /struts/sandbox/trunk/overdrive/Nexus: Core/ Core/Helpers/ Core/Tables/ Core/Validators/ Extras/Spring/ Test/ Test/Commands/ Test/Resources/Command/

Author: husted
Date: Wed Jun 15 09:23:51 2005
New Revision: 190773

URL: http://svn.apache.org/viewcvs?rev=190773&view=rev
Log:
OVR-8
OVR-12
OVR-13
* Add ListAllTest and ObjectByKeyTest, with domain objects.
* Refine IRequestCatalog API. 
* Add IFieldTable and IFieldContext with default implementation. 
* Add IValidator and IValidatorContext with default implementation. 
* Add standard ConvertInput and FormatOutput Commands.
* Change *Context terms to *Request.
* For property Tokens, change from UPPER_CASE to CamelCase to match property names.

Added:
    struts/sandbox/trunk/overdrive/Nexus/Core/IRequestChain.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/RequestChain.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldContext.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldTable.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ConvertInput.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Validators/FormatOutput.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidator.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Validators/Validator.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ValidatorContext.cs
    struts/sandbox/trunk/overdrive/Nexus/Test/Commands/ObjectByKey.cs
    struts/sandbox/trunk/overdrive/Nexus/Test/ObjectByKeyTest.cs
Modified:
    struts/sandbox/trunk/overdrive/Nexus/Core/Core.csproj
    struts/sandbox/trunk/overdrive/Nexus/Core/Helpers/ViewHelper.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCatalog.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCommand.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/IRequestContext.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/RequestCommand.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/RequestContext.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldContext.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldTable.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Tokens.cs
    struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidatorContext.cs
    struts/sandbox/trunk/overdrive/Nexus/Extras/Spring/Catalog.cs
    struts/sandbox/trunk/overdrive/Nexus/Test/ControllerTest.cs
    struts/sandbox/trunk/overdrive/Nexus/Test/Objects.xml
    struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/AppConfig.xml
    struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/Catalog.xml
    struts/sandbox/trunk/overdrive/Nexus/Test/Test.csproj

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/Core.csproj
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Core.csproj?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Core.csproj (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Core.csproj Wed Jun 15 09:23:51 2005
@@ -99,6 +99,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "IRequestChain.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "IRequestCommand.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -109,6 +114,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "RequestChain.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "RequestCommand.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -134,6 +144,16 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "Tables\FieldContext.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Tables\FieldTable.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "Tables\IFieldContext.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -144,7 +164,32 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "Validators\ConvertInput.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Validators\FormatOutput.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Validators\IValidator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "Validators\IValidatorContext.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Validators\Validator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Validators\ValidatorContext.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/Helpers/ViewHelper.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Helpers/ViewHelper.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Helpers/ViewHelper.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Helpers/ViewHelper.cs Wed Jun 15 09:23:51 2005
@@ -33,7 +33,7 @@
 			get
 			{
 				if (_Context == null)
-					_Context = Catalog.GetContext (Command);
+					_Context = Catalog.GetRequest (Command);
 				return _Context;
 			}
 		}

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCatalog.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCatalog.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCatalog.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCatalog.cs Wed Jun 15 09:23:51 2005
@@ -1,3 +1,4 @@
+using System.Collections;
 using Agility.Core;
 /*
  * Copyright 2005 The Apache Software Foundation.
@@ -24,34 +25,53 @@
 	/// 
 	public interface IRequestCatalog : ICatalog
 	{
+
 		/// <summary>
-		/// Obtain object instance for name.
+		/// Obtain a IRequestContext for command ID, 
+		/// including embedded resources.
 		/// </summary>
-		/// <param name="name">ID for object to return</param>
-		/// <returns>Instantiated object corresonding to name</returns>
+		/// <param name="command">Our command ID</param>
+		/// <returns>IRequestContext with embedded resources.</returns>
 		/// 
-		object GetObject (string name);
+		IRequestContext GetRequest (string command);
 
 		/// <summary>
-		/// Obtain new NexusContext for command, 
+		/// Obtain a IRequestContext for command ID, 
+		/// including embedded resources, 
+		/// and process string-based input. 
+		/// </summary>
+		/// <param name="command">Our command ID</param>
+		/// <param name="input">Our input values</param>
+		/// <returns>IRequestContext with embedded resources.</returns>
+		/// 
+		IRequestContext GetRequest (string command, IDictionary input);
+
+		/// <summary>
+		/// Obtain a IRequestContext for the command, 
 		/// including embedded resources.
 		/// </summary>
 		/// <param name="command">Our command</param>
-		/// <returns>NexusContext with embedded resources.</returns>
+		/// <returns>IRequestContext with embedded resources.</returns>
 		/// 
-		IRequestContext GetContext (IRequestCommand command);
+		IRequestContext GetRequest (IRequestCommand command);
 
 		/// <summary>
-		/// Obtain and execute the IRequestContext.
+		/// Obtain and execute a IRequestContext.
 		/// </summary>
-		/// <param name="command">Our command name</param>
+		/// <param name="command">Our command ID</param></param>
 		/// <returns>Context after execution</returns>
 		/// 
-		IRequestContext ExecuteContext (string command);
+		IRequestContext ExecuteRequest (string command);
 
+		/// <summary>
+		/// Execute a IRequestContext.
+		/// </summary>
+		/// <param name="context">Context to execute</param>
+		/// 
+		void ExecuteRequest (IRequestContext context);
 
 		/// <summary>
-		/// Execute a Command as part of a View layer chain.
+		/// Execute a IRequestContext as part of a View layer chain.
 		/// </summary>
 		/// <remarks><p>
 		/// Among other things, the View layer chain may transfer 

Added: struts/sandbox/trunk/overdrive/Nexus/Core/IRequestChain.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/IRequestChain.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/IRequestChain.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/IRequestChain.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,11 @@
+using Agility.Core;
+
+namespace Nexus.Core
+{
+	/// <summary>
+	/// Composite IChain with IRequestCommand.
+	/// </summary>
+	public interface IRequestChain: IChain, IRequestCommand
+	{
+	}
+}

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCommand.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCommand.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCommand.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/IRequestCommand.cs Wed Jun 15 09:23:51 2005
@@ -13,12 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+using System.Collections;
 using Agility.Core;
 
 namespace Nexus.Core
 {
 	/// <summary>
-	/// Use an IRequestContext to process a Command [OVR-9]
+	/// Extend ICommand to utilize an IRequestContext [OVR-9]
 	/// </summary>
 	/// <remarks><p>
 	/// Rather than have each command cast its context to an 
@@ -39,12 +40,100 @@
 		string ID { get; set; }
 
 		/// <summary>
+		/// An identifier for a Query associated with this Command (if any).
+		/// </summary>
+		/// <remarks>
+		/// If Query is not set, then ID is returned instead. 
+		/// (The default QueryID is the command ID.) 
+		/// </remarks>
+		/// <returns>An identifier for this Command.</returns>
+		string QueryID { get; set; }
+
+		/// <summary>
 		/// Factory method to provide an empty context that can be used 
 		/// with the Command instance.
 		/// </summary>
 		/// <returns>Context instance with Command ID set.</returns>
 		/// 
 		IRequestContext NewContext ();
+
+		/// <summary>
+		/// Field IDs required by this Command.
+		/// </summary>
+		/// <remarks><p>
+		/// If requisite fields are not present in the main Context, 
+		/// appropriate errors should be posted to the Errors property, 
+		/// so that the client can correct the oversight and resubmit the request.
+		/// </p><p>
+		/// The RelatedIDs property may be used by the command itself, 
+		/// or by a collaborating "conversion" command, 
+		/// to confirm that related fields, when present, are in the expected format. 
+		/// </p><p>
+		/// The RelatedIDs property may be used by the command itself, 
+		/// or by a collaborating "validation" command, 
+		/// to confirm that related fields, when present, are in the expected format. 
+		/// </p></remarks>
+		IList RequiredIDs { get; set; }
+
+		/// <summary>
+		/// Add a IList of IDs to the list of {@link RequiredIds}.
+		///</summary>
+		///<remarks>
+		IList AddRequiredIDs { set; }
+
+		/// <summary>
+		/// Field IDs related to this Command, including any RequiredIDs.
+		/// </summary>
+		/// <remarks><p>
+		/// If a Field ID is not specified as a  RelatedID or a RequiredID, 
+		/// than it may not be passed from the Criteria to the main Context, 
+		/// and so will not be available to the Command. 
+		/// </p><p>
+		/// As the field is passed from the Fieldstate to the main Context, 
+		/// it may also be converted to the appropriate DataType or string format. 
+		/// A collaborating Command may reference the FieldTable in a INexusContext 
+		/// to ascertain the expected type or format for a value and 
+		/// to obtain the appropriate error messages for each field. 
+		/// </p><p>
+		/// The RelatedIDs property may be used by the command itself, 
+		/// or by a collaborating "conversion" command, 
+		/// to confirm that related fields, when present, are in the expected format. 
+		/// </p><p>
+		/// Since posting errors and messages is a specialized concern, 
+		/// it is recommended that collaborating Commands handle validation and confirmation.
+		/// </p><p>
+		/// A collaborating Command may reference the FieldTable in a INexusContext 
+		/// to ascertain the expected format for a value and 
+		/// to obtain the appropriate error messages for each field. 
+		/// </p></remarks>
+		IList RelatedIDs { get; set; }
+
+		/// <summary>
+		/// Add a IList of IDs to the list of {@link RelatedIds}.
+		///</summary>
+		///<remarks>
+		IList AddRelatedIDs { set; }
+
+		/// <summary>
+		/// Field IDs provided during the processing of a Chain. 
+		/// </summary>
+		/// <remarks><p>
+		/// When Commands are chained, the output from one Command may be  used 
+		/// as input for another Command. If a collaborating Command is 
+		/// validating the Criteria for required input, prior to processing, 
+		/// then Runtime FieldIDs may be excluded from the set of RequiredIDs. 
+		/// </p><p>
+		/// The RuntimeIDs are expected to be set on a Chain rather than an individual 
+		/// Command. The property is a member of the INexusCommand interface so that 
+		/// Command and Chains can observe the substitution principle.
+		/// </p></remarks>
+		IList RuntimeIDs { get; set; }
+
+		/// <summary>
+		/// Add a IList of IDs to the list of {@link RuntimeIds}.
+		///</summary>
+		///<remarks>
+		IList AddRuntimeIDs { set; }
 
 		/// <summary>
 		/// Operations to perform with HelperContext.

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/IRequestContext.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/IRequestContext.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/IRequestContext.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/IRequestContext.cs Wed Jun 15 09:23:51 2005
@@ -27,39 +27,51 @@
 	/// An IRequestContext can predefine whatever properties we need for 
 	/// storing input, output, messages, and other common attributes, 
 	/// including Locale (or Culture) and user credentials. 
+	/// </p><p>
+	/// A key member is the FieldTable. 
+	/// The FieldTable uses XForms terminology for its members 
+	/// and IRequestContext members follow suit. 
+	/// For example, "errors" are called "Alerts" and generic 
+	/// messages are called "Hints, 
+	/// since these are terms used by the FieldTable and XForms.
 	/// </p></remarks>
 	/// 
 	public interface IRequestContext : IContext
 	{
+
+		#region Processing 
+
 		/// <summary>
-		/// Identifier for the top-level Command (or Chain) processing 
+		/// Identify the top-level Command (or Chain) processing 
 		/// this Context.
 		/// </summary>
 		/// <remarks><P>
-		/// Corresponds to ID of INexusCommand for the initial Command 
-		/// or Chain.
+		/// The Command property corresponds to ID of INexusCommand 
+		/// for the initial Command or Chain.
 		/// </P></remarks>
 		/// 
 		string Command { get; set; }
 
 		/// <summary>
-		/// Instance of the top-level Command (or Chain) processing this 
-		/// Context.
+		/// Provide the top-level Command (or Chain) processing this Context.
 		/// </summary>
 		/// <remarks><p>
-		/// Corresponds to ID of INexusCommand for the initial Command 
-		/// or Chain.
+		/// Command corresponds to ID of INexusCommand for the 
+		/// initial Command or Chain.
 		/// </p></remarks>
 		/// 
 		IRequestCommand CommandBin { get; set; }
 
 
 		/// <summary>
-		/// Instance of the global Field Table for this application.
+		/// Provide the Field Table for this Context.
 		/// </summary>
 		/// <remarks><p>
-		/// Corresponds to ID of INexusCommand for the initial Command or 
-		/// Chain.
+		/// The default implementation uses the Catalog to inject the global 
+		/// Field Table reference. 
+		/// The Context, and members with access to a Context, 
+		/// can use the FieldTable to validate and format values, 
+		/// and even to create controls that display values.
 		/// </p></remarks>
 		/// 
 		IFieldTable FieldTable { get; set; }
@@ -111,7 +123,55 @@
 		object Outcome { get; set; }
 
 		/// <summary>
-		/// A list of alert (or error) messages, 
+		/// Indicate whether a Criteria is present.
+		/// </summary>
+		/// <returns>True if a Criteria is present.</returns>
+		bool HasCriteria ();
+
+		/// <summary>
+		/// Provide an optional subcontext containing input or output 
+		/// values, usually expressed as display strings.
+		/// </summary>
+		/// <remarks>
+		/// <p>
+		/// Criteria is provided for Commands that accept input 
+		/// from other components which may need to be validated, 
+		/// converted, or formatted before use.
+		/// If the proposed FieldState is accepted, 
+		/// the entries may be merged into the root Context, 
+		/// perhaps after type conversion or formatting tasks.
+		/// If the proposed FieldState is not accepted, 
+		/// the entries are not merged into the root Context, 
+		/// and there should be Errors or a Fault explaining 
+		/// why the FieldState (e.g input) cannot be accepted.
+		/// </p>
+		/// <p>
+		/// In practice, it is expected, but not required, that 
+		/// all the FieldState entries will contain string values.
+		/// </p>
+		/// <p>
+		/// Commands should only act on the Criteria in order 
+		/// to transfer values between the FieldState and the 
+		/// root Context. 
+		/// Conventional Commands will look to the root Context 
+		/// for the state and make any expected changes 
+		/// or additions directly to the root context.
+		/// FieldState is not expected to be used by a Commands 
+		/// unless input is being submitted from an untrusted or 
+		/// naive component, or needs to be transformed for use 
+		/// by a display component.
+		/// </p>
+		/// </remarks>
+		IDictionary Criteria { get; set; }
+
+		#endregion 
+
+		#region Messaging
+
+		string FormatTemplate (string template, string value);
+
+		/// <summary>
+		/// Record a list of alert (or error) messages, 
 		/// keyed by the field causing the message, 
 		/// or to a magic global key.
 		/// </summary>
@@ -129,6 +189,23 @@
 		void AddAlert (string template);
 
 		/// <summary>
+		/// Add an alert message, creating the context if needed. 
+		/// </summary>
+		/// <remarks>
+		/// Multiple messages can be added for a key and retrieved as a List.
+		/// </remarks>
+		/// <param name="template">Message template.</param>
+		/// <param name="message">Message key.</param>
+		void AddAlert (string template, string message);
+
+		/// <summary>
+		/// Add a formatted Alert error message
+		/// for the given field key via the FieldTable.
+		/// </summary>
+		/// <param name="key">Key from the FieldTable</param>
+		void AddAlertForField (string key);
+
+		/// <summary>
 		/// Indicate whether alerts exist.
 		/// </summary>
 		/// <returns>True if there are alerts.</returns>
@@ -136,13 +213,8 @@
 		bool HasAlerts { get; }
 
 		/// <summary>
-		/// An Exception, if thrown.
+		/// Record an Exception, if thrown.
 		/// </summary>
-		/// <remark>
-		/// A IViewContext is readonly, 
-		/// but another interface (e.g. IHelperContext) may extend to add a 
-		/// setter, if needed.
-		/// </remark>
 		/// 
 		Exception Fault { get; set; }
 
@@ -161,7 +233,7 @@
 		bool IsNominal { get; }
 
 		/// <summary>
-		/// A list of hint (advisory or warning) messages (!errors), 
+		/// Record hint (advisory or warning) messages (!errors), 
 		/// keyed by the field causing the message, 
 		/// or to a magic global key.
 		/// </summary>
@@ -194,5 +266,6 @@
 		/// 
 		bool HasHints { get; }
 
+		#endregion
 	}
 }

Added: struts/sandbox/trunk/overdrive/Nexus/Core/RequestChain.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/RequestChain.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/RequestChain.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/RequestChain.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,59 @@
+using System;
+using System.Collections;
+using Agility.Core;
+
+namespace Nexus.Core
+{
+	/// <summary>
+	/// Implement IRequestChain.
+	/// </summary>
+	public class RequestChain : RequestCommand, IRequestChain
+	{
+
+		private Chain chain = new Chain ();
+
+		public void AddCommand (ICommand _command)
+		{
+			IRequestCommand command = _command as IRequestCommand;
+			if (null == command)
+				throw new ArgumentNullException ("RequestChain.AddCommand", "_command");
+
+			chain.AddCommand (command);
+
+			// Composite Required and Related
+			IList _RequiredIDs = command.RequiredIDs;
+			if (null != _RequiredIDs) this.AddRequiredIDs = _RequiredIDs;
+
+			IList _RelatedIDs = command.RelatedIDs;
+			if (null != _RelatedIDs) this.AddRelatedIDs = _RelatedIDs;
+		}
+
+		public IList AddCommands
+		{
+			set
+			{
+				foreach (ICommand command in value)
+				{
+					AddCommand (command);
+				}
+			}
+		}
+
+		public override bool Execute (IContext context)
+		{
+			return chain.Execute (context);
+		}
+
+		public ICommand[] GetCommands ()
+		{
+			return (chain.GetCommands ());
+
+		}
+
+		public override bool RequestExecute (IRequestContext context)
+		{
+			return Execute (context);
+		}
+
+	}
+}

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/RequestCommand.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/RequestCommand.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/RequestCommand.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/RequestCommand.cs Wed Jun 15 09:23:51 2005
@@ -13,12 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+using System;
+using System.Collections;
 using Agility.Core;
 
 namespace Nexus.Core
 {
 	/// <summary>
-	/// Abstract IRequestCommand; subclass must implement RequestExecute.
+	/// Implement IRequestCommand, leaving RequestExecute abstract.
 	/// </summary>
 	/// 
 	public abstract class RequestCommand : IRequestCommand
@@ -43,11 +45,109 @@
 			set { _ID = value; }
 		}
 
+		private string _QueryID = null;
+		public virtual string QueryID
+		{
+			get
+			{
+				if (null == _QueryID) return ID;
+				else return _QueryID;
+			}
+			set { _QueryID = value; }
+		}
+
 		public virtual IRequestContext NewContext ()
 		{
 			// Return a new instance on each call.
 			// ISSUE: Spring?
 			return new RequestContext (ID);
+		}
+
+		private IList _RequiredIDs = null;
+		public virtual IList RequiredIDs
+		{
+			get { return _RequiredIDs; }
+			set { _RequiredIDs = value; }
+		}
+
+		public IList AddRequiredIDs
+		{
+			set
+			{
+				if (value == null)
+					throw new ArgumentNullException ("BaseNexusCommand.AddRequiredIDs", "value");
+				IList list = RequiredIDs;
+				if (null == list)
+					RequiredIDs = value;
+				else
+				{
+					IEnumerator elements = value.GetEnumerator ();
+					while (elements.MoveNext ())
+					{
+						string i = elements.Current as string;
+						bool need = (list.IndexOf (i) < 0);
+						if (need) list.Add (i);
+					}
+				}
+			}
+		}
+
+		private IList _RelatedIDs = null;
+		public virtual IList RelatedIDs
+		{
+			get { return _RelatedIDs; }
+			set { _RelatedIDs = value; }
+		}
+
+		public IList AddRelatedIDs
+		{
+			set
+			{
+				if (value == null)
+					throw new ArgumentNullException ("BaseNexusCommand.AddRelatedIDs", "value");
+				IList list = RelatedIDs;
+				if (null == list)
+					RelatedIDs = value;
+				else
+				{
+					IEnumerator elements = value.GetEnumerator ();
+					while (elements.MoveNext ())
+					{
+						string i = elements.Current as string;
+						bool need = (list.IndexOf (i) < 0);
+						if (need) list.Add (i);
+					}
+				}
+			}
+		}
+
+		private IList _RuntimeIDs = null;
+		public virtual IList RuntimeIDs
+		{
+			get { return _RuntimeIDs; }
+			set { _RuntimeIDs = value; }
+		}
+
+		public IList AddRuntimeIDs
+		{
+			set
+			{
+				if (value == null)
+					throw new ArgumentNullException ("BaseNexusCommand.AddRuntimeIDs", "value");
+				IList list = RuntimeIDs;
+				if (null == list)
+					RuntimeIDs = value;
+				else
+				{
+					IEnumerator elements = value.GetEnumerator ();
+					while (elements.MoveNext ())
+					{
+						string i = elements.Current as string;
+						bool need = (list.IndexOf (i) < 0);
+						if (need) list.Add (i);
+					}
+				}
+			}
 		}
 
 		public abstract bool RequestExecute (IRequestContext context);

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/RequestContext.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/RequestContext.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/RequestContext.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/RequestContext.cs Wed Jun 15 09:23:51 2005
@@ -15,17 +15,37 @@
  */
 using System;
 using System.Collections;
+using System.Text;
 using Agility.Core;
 using Nexus.Core.Tables;
 
 namespace Nexus.Core
 {
 	/// <summary>
-	/// Concrete IRequestContext implementation.
+	/// Implement IRequestContext.
 	/// </summary>
 	/// 
 	public class RequestContext : Context, IRequestContext
 	{
+
+		/// <summary>
+		/// Express state as a key=value list.
+		/// </summary>
+		/// <returns>Formatted string representing state.</returns>
+		public override string ToString ()
+		{
+			StringBuilder sb = new StringBuilder ();
+			foreach (DictionaryEntry e in this)
+			{
+				sb.Append ("[");
+				sb.Append (e.Key);
+				sb.Append ("=");
+				sb.Append (e.Value.ToString ());
+				sb.Append ("], ");
+			}
+			return sb.ToString ();
+		}
+
 		/// <summary>
 		/// Convenience constructor to set Command on instantiation.
 		/// </summary>
@@ -80,6 +100,32 @@
 		}
 
 		/// <summary>
+		/// Instantiate Criteria, if needed.
+		/// </summary>
+		private void LazyCriteria ()
+		{
+			// Naive, but we expect a Context instance to be single-threaded.
+			if (this [Tokens.Criteria] == null)
+				this [Tokens.Criteria] = new Hashtable (); // TODO: Spring?
+		}
+
+		public IDictionary Criteria
+		{
+			get
+			{
+				LazyCriteria ();
+				return this [Tokens.Criteria] as IDictionary;
+			}
+			set { this [Tokens.Criteria] = value; }
+		}
+
+		public bool HasCriteria ()
+		{
+			return ContainsKey (Tokens.Criteria);
+		}
+
+
+		/// <summary>
 		/// Convenience method to lazily instantiate a message store.
 		/// </summary>
 		/// <param name="template">Message template to add to the queue.</param>
@@ -106,6 +152,13 @@
 			list.Add (template);
 		}
 
+		public string FormatTemplate (string template, string value)
+		{
+			StringBuilder sb = new StringBuilder ();
+			sb.AppendFormat (template, value);
+			return sb.ToString ();
+		}
+
 		public IDictionary Alerts
 		{
 			get { return this [Tokens.Alerts] as IDictionary; }
@@ -115,6 +168,17 @@
 		public void AddAlert (string template)
 		{
 			AddStore (template, Tokens.GenericMessage, Tokens.Alerts);
+		}
+
+		public void AddAlert (string template, string queue)
+		{
+			AddStore (template, queue, Tokens.Alerts);
+		}
+
+		public void AddAlertForField (string key)
+		{
+			string message = FormatTemplate (FieldTable.Alert (key), key);
+			AddAlert (message, key);
 		}
 
 		public bool HasAlerts

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldContext.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldContext.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldContext.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldContext.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,82 @@
+using System;
+using Agility.Core;
+using Nexus.Core.Tables;
+
+namespace Nexus.Core.Tables
+{
+	/// <summary>
+	/// Concrete IFieldContext implementation.
+	/// </summary>
+	[Serializable]
+	public class FieldContext : Context, IFieldContext
+	{
+		public FieldContext () : base ()
+		{
+			ControlTypeName = Tokens.INPUT_CONTROL; // Default
+		}
+
+		public string Alert
+		{
+			get { return this [Tokens.Alert] as string; }
+			set { this [Tokens.Alert] = value; }
+		}
+
+		public string ControlTypeName
+		{
+			get { return this [Tokens.ControlTypeName] as string; }
+			set { this [Tokens.ControlTypeName] = value; }
+		}
+
+		public string DataFormat
+		{
+			get { return this [Tokens.DataFormat] as string; }
+			set { this [Tokens.DataFormat] = value; }
+		}
+
+		public Type DataType
+		{
+			get { return this [Tokens.DataType] as Type; }
+			set
+			{
+				this [Tokens.DataType] = value;
+				this [Tokens.DataTypeName] = value.FullName;
+			}
+		}
+
+		public string DataTypeName
+		{
+			get { return this [Tokens.DataTypeName] as string; }
+			set
+			{
+				this [Tokens.DataType] = Type.GetType (value);
+				this [Tokens.DataTypeName] = value;
+			}
+		}
+
+		public string Hint
+		{
+			get { return this [Tokens.Hint] as string; }
+			set { this [Tokens.Hint] = value; }
+		}
+
+		public string Help
+		{
+			get { return this [Tokens.Help] as string; }
+			set { this [Tokens.Help] = value; }
+		}
+
+		public string ID
+		{
+			get { return this [Tokens.ID] as string; }
+			set { this [Tokens.ID] = value; }
+		}
+
+
+		public string Label
+		{
+			get { return this [Tokens.Label] as string; }
+			set { this [Tokens.Label] = value; }
+		}
+
+	}
+}
\ No newline at end of file

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldTable.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldTable.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldTable.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Tables/FieldTable.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,293 @@
+using System;
+using System.Collections;
+using Agility.Core;
+using Nexus.Core.Validators;
+
+namespace Nexus.Core.Tables
+{
+	/// <summary>
+	/// Default implementation of IFieldTable.
+	/// </summary>
+	/// <remarks><p>
+	/// Validator
+	/// * Needs configurable nullvalue support
+	/// ** String, nullValue=""
+	/// ** Double, nullValue=0.0"
+	/// ** DataType, allowNull
+	/// * If they give us something, and it fails conversion, then validation fails. 
+	/// * If they give us null or an empty string, and the property has a nullValue, then the nullValue is used. 
+	/// * If they give us null or an empty string, or the nullValue, and the property is required, then validation fails. 
+	/// </p></remarks>
+	[Serializable]
+	public class FieldTable : Context, IFieldTable
+	{
+		private bool _Strict = false;
+		public virtual bool Strict
+		{
+			get { return _Strict; }
+			set { _Strict = value; }
+		}
+
+		public virtual IFieldContext AddField
+		{
+			set
+			{
+				if (value == null)
+					throw new ArgumentNullException ("value", "Agility.Nexus.FieldTable.AddField");
+				this [value.ID] = value;
+			}
+		}
+
+		public virtual IList AddFields
+		{
+			set
+			{
+				if (value == null)
+					throw new ArgumentNullException ("value", "Agility.Nexus.FieldTable.AddFields");
+				IEnumerator elements = value.GetEnumerator ();
+				while (elements.MoveNext ()) AddField = elements.Current as IFieldContext;
+			}
+		}
+
+		public virtual string Alert (string id)
+		{
+			return Get (id).Alert;
+		}
+
+		private bool IsStringType (Type dataType)
+		{
+			return ((typeof (String) == dataType) || (typeof (string) == dataType) || (null == dataType));
+		}
+
+		public bool IsRichControl (string name)
+		{
+			return !(Tokens.INPUT_CONTROL.Equals (name));
+		}
+
+		public virtual bool Convert (IValidatorContext context)
+		{
+			bool okay = false;
+
+			// FIXME: This is begging for a Chain
+
+			#region non DataTypes
+
+			string id = context.FieldKey;
+			string source = context.Source as string;
+			IFieldContext fieldContext = Get (id);
+			if ((fieldContext == null))
+			{
+				if (Strict)
+					throw new ArgumentNullException ("Agility.Nexus.FieldTable.Convert", id);
+				else
+				{
+					context.Target = source;
+					return true;
+				}
+			}
+
+			if (IsRichControl (fieldContext.ControlTypeName))
+			{
+				context.Target = source;
+				return true;
+			}
+
+			#endregion
+
+			#region DataTypes
+
+			bool processed = false;
+
+			if ((typeof (DateTime) == fieldContext.DataType))
+			{
+				processed = true;
+				if (IsInput (source))
+				{
+					DateTime t = DateTime_Convert (fieldContext, source);
+					bool isDateTimeEmpty = DateTime_Empty.Equals (t);
+					okay = !isDateTimeEmpty;
+					context.Target = t;
+				}
+				else
+				{
+					context.Target = null; // We could use DateTime_Empty here,
+					okay = true; //  but there's an issue with iBATIS
+				}
+			}
+
+			if (IsStringType (fieldContext.DataType))
+			{
+				processed = true;
+				context.Target = String_Convert (fieldContext, source);
+				okay = true;
+			}
+
+			// TODO: Other types. 
+
+			#endregion
+
+			if (!processed)
+				throw new ArgumentOutOfRangeException ("Nexus.Core.FieldTable.DataType", id);
+
+			return okay;
+		}
+
+		public virtual bool Format (IValidatorContext context)
+		{
+			bool okay = false;
+			string id = context.FieldKey;
+			object source = context.Source;
+			IFieldContext fieldContext = Get (id);
+			if ((fieldContext == null))
+			{
+				if (Strict)
+					throw new ArgumentNullException ("Nexus.Core.FieldTable", "Format");
+				else
+				{
+					context.Target = (source == null) ? null : source.ToString ();
+					return true;
+				}
+			}
+
+			if (IsRichControl (fieldContext.ControlTypeName))
+			{
+				context.Target = source;
+				return true;
+			}
+
+			bool processed = false;
+			if ((typeof (DateTime) == fieldContext.DataType))
+			{
+				processed = true;
+				SByte dbNull = 0;
+				bool isDateTimeEmpty = ((null == source) || (DBNull.Value.Equals (source)) || (dbNull.Equals (source) || String.Empty.Equals (source)));
+				// We could use DateTime_Empty here, but there's an issue with iBATIS
+				if (isDateTimeEmpty)
+				{
+					context.Target = String.Empty;
+					okay = true;
+				}
+				else
+				{
+					string target = DateTime_Format (fieldContext, source);
+					context.Target = target;
+					okay = IsInput (target);
+				}
+			}
+
+			if (IsStringType (fieldContext.DataType))
+			{
+				processed = true;
+				context.Target = String_Format (fieldContext, source);
+				okay = true;
+			}
+
+			// TODO: Other types. 
+
+			if (!processed)
+				throw new ArgumentOutOfRangeException ("Agility.Nexus.FieldTable.DataType", id);
+
+			return okay;
+		}
+
+		public virtual IFieldContext Get (string id)
+		{
+			IFieldContext fieldContext = this [id] as IFieldContext;
+			bool problem = ((fieldContext == null) && (Strict));
+			if (problem)
+				throw new ArgumentNullException ("Agility.Nexus.FieldTable", "Get");
+			return fieldContext;
+		}
+
+
+		/// <summary>
+		/// Determine whether string is null or empty.
+		/// </summary>
+		/// <param name="v">String to test.</param>
+		/// <returns>True if the string is valid input (not null and not empty).</returns>
+		/// 
+		private bool IsInput (string v)
+		{
+			return ((v != null) && (!String.Empty.Equals (v)));
+		}
+
+		#region DateTime
+
+		// TODO: Create a IDataTrip interface with Convert and Format methods. 
+		// The runtime instances could then be injected into FieldTable
+		// or added to a list, for extensibility
+
+		private DateTime DateTime_Empty = DateTime.MinValue;
+
+		/// <summary>
+		/// Substitute default value (MinValue) if conversion fails. 
+		/// </summary>
+		/// <param name="fieldContext">Our field definition.</param>
+		/// <param name="input">The string to convert.</param>
+		/// <returns>A DateTime value, using MinValue to represent failure.</returns>
+		public DateTime DateTime_Convert (IFieldContext fieldContext, string input)
+		{
+			DateTime t = DateTime_Empty;
+			try
+			{
+				// t = System.Convert.ToDateTime (input);
+				t = System.Convert.ToDateTime (input);
+			}
+			catch (InvalidCastException e)
+			{
+				e = e; // silly assignment
+			}
+			catch (FormatException e)
+			{
+				e = e; // silly assignment
+			}
+			return t;
+		}
+
+		/// <summary>
+		/// Render DateTime value using the DataFormat string, 
+		/// or an empty string if value is MinValue or an invalid type.
+		/// </summary>
+		/// <param name="fieldContext">Our field definition.</param>
+		/// <param name="value">The value to format.</param>
+		/// <returns>Formatted representation or an empty string.</returns>
+		public string DateTime_Format (IFieldContext fieldContext, object value)
+		{
+			DateTime t = DateTime_Empty;
+			try
+			{
+				t = (DateTime) value;
+			}
+			catch (InvalidCastException e)
+			{
+				e = e;
+			}
+			if (DateTime_Empty.Equals (t)) return String.Empty;
+			else return t.ToString (fieldContext.DataFormat);
+		}
+
+		#endregion
+
+		#region Utilities
+
+		private string String_Empty = String.Empty;
+
+		public string String_Convert (IFieldContext fieldContext, string input)
+		{
+			bool isNull = (input == null);
+			return isNull ? String_Empty : input;
+			// If null, return empty string rather than null
+
+		}
+
+		public string String_Format (IFieldContext fieldContext, object value)
+		{
+			string t = String_Empty;
+			bool valid = (value != null);
+			string format = (fieldContext.DataFormat != null) ? fieldContext.DataFormat : String.Empty;
+			return valid ? String.Format (format, value) : t;
+		}
+
+		#endregion
+	}
+}
\ No newline at end of file

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldContext.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldContext.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldContext.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldContext.cs Wed Jun 15 09:23:51 2005
@@ -4,14 +4,21 @@
 namespace Nexus.Core.Tables
 {
 	/// <summary>
-	/// Properties common to controls, including Alert, Constraints, 
-	/// ControlType, and DataType. 
+	/// Provide properties common to controls, 
+	/// including Alert, Constraints, ControlType, and DataType. 
 	/// </summary>
 	/// <remark><p>
-	/// Validation commands can use the FieldContext properties to verify 
-	/// input. 
+	/// Validation commands can use the FieldContext properties 
+	/// to verify input. 
 	/// The FieldContext entries are made available through a FieldTable.
-	/// </p></remark>
+	/// The FieldContext members follow XForms terminology. 
+	/// </p>
+	/// <p>
+	/// XForms [http://www.w3.org/MarkUp/Forms/]. 
+	/// XForms Controls [http://www.orbeon.com/ops/doc/processors-xforms].
+	/// XPath 2.0 for .NET [http://sourceforge.net/projects/saxondotnet/].
+	/// </p>
+	/// </remark>
 	/// 
 	public interface IFieldContext : ISerializable
 	{
@@ -22,8 +29,14 @@
 		string Alert { get; set; }
 
 		/// <summary>
-		/// Cannonical name of the Control Type (input, select, et al.).
+		/// Name for the default Control Type.
 		/// </summary>
+		/// <remarks><p>
+		/// Standard control types are: input, secret, textarea, select1, select, submit, upload.
+		/// </p><p>
+		/// XForms distinguishes between Lists, Radio Buttons, and CheckBoxes through additional 
+		/// parameters. For now, all three can be identified as select1 or select.
+		/// </p></remarks>
 		/// 
 		string ControlTypeName { get; set; }
 
@@ -34,10 +47,13 @@
 		string DataFormat { get; set; }
 
 		/// <summary>
-		/// Type of native data - Boolean, Byte Char, DateTime, Decimal, 
-		/// Double, Int16, Int32, Int64, SByte, Single, String, TimeSpan, 
-		/// UInt16, UInt32, UInt64.
+		/// Type of native data.
 		/// </summary>
+		/// <remarks>
+		/// Standard data types are: Boolean, Byte Char, DateTime, Decimal, 
+		/// Double, Int16, Int32, Int64, SByte, Single, String, TimeSpan, 
+		/// UInt16, UInt32, UInt64
+		/// </remarks>
 		/// 
 		Type DataType { get; set; }
 
@@ -48,6 +64,12 @@
 		string DataTypeName { get; set; }
 
 		/// <summary>
+		/// Help - Gets or sets text for a context-sensitive help screen.
+		/// </summary>
+		/// 
+		string Help { get; set; }
+
+		/// <summary>
 		/// Hint - Gets or sets an onscreen or hover hint.
 		/// </summary>
 		/// 
@@ -60,7 +82,7 @@
 		string ID { get; set; }
 
 		/// <summary>
-		/// the label for the control.
+		/// The label for the control.
 		/// </summary>
 		/// 
 		string Label { get; set; }

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldTable.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldTable.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldTable.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Tables/IFieldTable.cs Wed Jun 15 09:23:51 2005
@@ -1,7 +1,7 @@
 using System.Collections;
 using System.Runtime.Serialization;
 using Agility.Core;
-using Nexus.Validators;
+using Nexus.Core.Validators;
 
 namespace Nexus.Core.Tables
 {

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/Tokens.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Tokens.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Tokens.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Tokens.cs Wed Jun 15 09:23:51 2005
@@ -47,16 +47,22 @@
 		*/
 		
 		/// <summary>
-		/// Token for a generic message property.
+		/// Token for Alert property.
 		/// </summary>
-		/// <remarks><p>
-		/// A dot is used to communicate the idea 
-		/// that the message catagory has no name
-		/// and to avoid using a language constant 
-		/// in a language-neutral content.
-		/// </p></remarks>
 		/// 
-		public const string GenericMessage = ".";
+		public const string Alert = "_Alert";
+
+		/// <summary>
+		/// Token for Alerts property.
+		/// </summary>
+		/// 
+		public const string Alerts = "_Alerts";
+
+		/// <summary>
+		/// Token for Catalog property.
+		/// </summary>
+		/// 
+		public const string Catalog = "_Catalog";
 
 		/// <summary>
 		/// Token for Command property.
@@ -71,27 +77,34 @@
 		public const string CommandBin = "_CommandBin";
 
 		/// <summary>
-		/// Token for Alerts property.
+		/// Token for ControlTypeName ControlTypeName.
 		/// </summary>
 		/// 
-		public const string Alerts = "_Alerts";
+		public const string ControlTypeName = "_ControlTypeName";
 
 		/// <summary>
-		/// Token for Hints property.
+		/// Token for Criteria property.
 		/// </summary>
-		public const string Hints = "_Hints";
+		/// 
+		public const string Criteria = "_Criteria";
 
 		/// <summary>
-		/// Token for FieldTable property.
+		/// Token for DataFormat DataFormat.
 		/// </summary>
 		/// 
-		public const string FieldTable = "_FieldTable";
+		public const string DataFormat = "_DataFormat";
 
 		/// <summary>
-		/// Token for FieldSet property.
+		/// Token for DataType DataType.
 		/// </summary>
 		/// 
-		public const string FieldSet = "_FieldSet";
+		public const string DataType = "_DataType";
+
+		/// <summary>
+		/// Token for DataTypeName DataTypeName.
+		/// </summary>
+		/// 
+		public const string DataTypeName = "_DataTypeName";
 
 		/// <summary>
 		/// Token for Fault property.
@@ -100,10 +113,55 @@
 		public const string Fault = "_Fault";
 
 		/// <summary>
-		/// Token for Prefix property.
+		/// Token for FieldSet property.
 		/// </summary>
 		/// 
-		public const string Prefix = "_Prefix";
+		public const string FieldSet = "_FieldSet";
+
+		/// <summary>
+		/// Token for FieldTable property.
+		/// </summary>
+		/// 
+		public const string FieldTable = "_FieldTable";
+
+		/// <summary>
+		/// Token for a generic message property.
+		/// </summary>
+		/// <remarks><p>
+		/// A dot is used to communicate the idea 
+		/// that the message catagory has no name
+		/// and to avoid using a language constant 
+		/// in a language-neutral content.
+		/// </p></remarks>
+		/// 
+		public const string GenericMessage = ".";
+
+		/// <summary>
+		/// Token for Hint property.
+		/// </summary>
+		public const string Hint = "_Hint";
+
+		/// <summary>
+		/// Token for Hints property.
+		/// </summary>
+		public const string Hints = "_Hints";
+
+		/// <summary>
+		/// Token for Help property.
+		/// </summary>
+		public const string Help = "_Help";
+
+		/// <summary>
+		/// Token for ID ID.
+		/// </summary>
+		/// 
+		public const string ID = "_ID";
+
+		/// <summary>
+		/// Token for Label Label.
+		/// </summary>
+		/// 
+		public const string Label = "_Label";
 
 		/// <summary>
 		/// Token for ListSuffix property.
@@ -118,16 +176,16 @@
 		public const string NullIfEmpty = "_NullIfEmpty";
 
 		/// <summary>
-		/// Token for SelectItemPrompt property.
+		/// Token for Prefix property.
 		/// </summary>
 		/// 
-		public const string SelectItemPrompt = "_SelectItemPrompt";
+		public const string Prefix = "_Prefix";
 
 		/// <summary>
-		/// Token for Catalog property.
+		/// Token for SelectItemPrompt property.
 		/// </summary>
 		/// 
-		public const string Catalog = "_Catalog";
+		public const string SelectItemPrompt = "_SelectItemPrompt";
 
 		#endregion
 
@@ -137,13 +195,34 @@
 		/// Token for the pre-op command element.
 		/// </summary>
 		/// 
-		public const string PRE_OP = "pre-op";
+		public const string PRE_OP_ID = "pre-op";
 
 		/// <summary>
 		/// Token for the post-op command element.
 		/// </summary>
 		/// 
-		public const string POST_OP = "post-op";
+		public const string POST_OP_ID = "post-op";
+
+		/// <summary>
+		/// Token for FieldTable command element.
+		/// </summary>
+		/// 
+		public const string FIELD_TABLE_ID = "FieldTable";
+
+
+		#endregion
+
+		#region Control Type Names
+
+		/// <summary>
+		/// Token for input Control Type Name.
+		/// </summary>
+		public const string INPUT_CONTROL = "input";
+
+		/// <summary>
+		/// Token for select Control Type Name.
+		/// </summary>
+		public const string SELECT_CONTROL = "select";
 
 		#endregion
 

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ConvertInput.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ConvertInput.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ConvertInput.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ConvertInput.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,15 @@
+namespace Nexus.Core.Validators
+{
+	/// <summary>
+	/// Convert all related fields from Criteria to the main context, 
+	/// adding an Alert message to Errors if a conversion fails.
+	/// </summary>
+	public class ConvertInput : Validator
+	{
+		public ConvertInput ()
+		{
+			Mode = MODE_INPUT;
+		}
+
+	}
+}
\ No newline at end of file

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Validators/FormatOutput.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Validators/FormatOutput.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Validators/FormatOutput.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Validators/FormatOutput.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,16 @@
+using Nexus.Core.Validators;
+
+namespace Nexus.Core.Validators
+{
+	/// <summary>
+	/// Format all related fields from the main context to Criteria, 
+	/// adding an error message to Alerts if formatting fails.
+	/// </summary>
+	public class FormatOutput : Validator
+	{
+		public FormatOutput ()
+		{
+			Mode = MODE_OUTPUT;
+		}
+	}
+}
\ No newline at end of file

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidator.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidator.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidator.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidator.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,14 @@
+using Nexus.Core;
+
+namespace Nexus.Core.Validators
+{
+	/// <summary>
+	/// A IValidator command is a NexusCommand that provides a message Template to use 
+	/// when validation fails.
+	/// </summary>
+	public interface IValidatorCommand : IRequestCommand
+	{
+		string Template { get; set; }
+		bool Continue { get; set; }
+	}
+}
\ No newline at end of file

Modified: struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidatorContext.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidatorContext.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidatorContext.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Validators/IValidatorContext.cs Wed Jun 15 09:23:51 2005
@@ -1,6 +1,6 @@
 using Agility.Core;
 
-namespace Nexus.Validators
+namespace Nexus.Core.Validators
 {
 	/// <summary>
 	/// Encapsulate values needed by standard IValidatorCommands [OVR-13].

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Validators/Validator.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Validators/Validator.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Validators/Validator.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Validators/Validator.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,169 @@
+using System;
+using System.Collections;
+using Agility.Nexus.Validators;
+using Nexus.Core.Tables;
+
+namespace Nexus.Core.Validators
+{
+	/// <summary>
+	/// A base class to use when implementating Validators. 
+	/// </summary>
+	/// <remarks>
+	/// Subclasses must provide a NexusExecute method.
+	/// </remarks>
+	public class Validator : RequestCommand, IValidatorCommand
+	{
+		#region Properties
+
+		private string _Template = null;
+		public virtual string Template
+		{
+			get { return _Template; }
+			set { _Template = value; }
+		}
+
+		private bool _Continue = false;
+		public virtual bool Continue
+		{
+			get { return _Continue; }
+			set { _Continue = value; }
+		}
+
+		public const bool MODE_INPUT = false;
+		public const bool MODE_OUTPUT = true;
+
+		private bool _Mode = MODE_INPUT;
+		public virtual bool Mode
+		{
+			get { return _Mode; }
+			set { _Mode = value; }
+		}
+
+		#endregion
+
+		public ICollection CombinedIDs (IRequestContext context)
+		{
+			IDictionary combined = new Hashtable ();
+			IList relatedIDs = context.CommandBin.RelatedIDs; // outer list
+			if (relatedIDs != null) foreach (string i in relatedIDs) combined [i] = i;
+			IList requiredIDs = context.CommandBin.RequiredIDs; // inner list
+			if (requiredIDs != null) foreach (string i in requiredIDs) combined [i] = i;
+			return combined.Keys;
+		}
+
+		#region ProcessRelated
+
+		public void AssertProcessRelated (IRequestContext context)
+		{
+			AssertProcessRequired (context);
+
+			IFieldTable table = context.FieldTable;
+			if (null == table)
+				throw new ArgumentNullException ("FieldTable", "BaseValidator.NexusExecute.AssertProcessRelated");
+		}
+
+		public virtual void ProcessRelated (IRequestContext context, bool mode)
+		{
+			AssertProcessRelated (context);
+
+			IDictionary fields = context.Criteria;
+			IFieldTable table = context.FieldTable;
+			ICollection related = CombinedIDs (context);
+			foreach (string key in related)
+			{
+				bool have = false;
+				bool okay = false;
+
+				switch (mode)
+				{
+					case MODE_INPUT:
+					{
+						have = (fields.Contains (key));
+						if (have)
+						{
+							string source = fields [key] as string;
+							// TODO: Spring?
+							IValidatorContext _context = new ValidatorContext (key, source);
+							okay = table.Convert (_context);
+							if (okay)
+								// set to main context
+								context [key] = _context.Target;
+						}
+						break;
+					}
+
+					case MODE_OUTPUT:
+					{
+						have = (context.Contains (key));
+						if (have)
+						{
+							object source = context [key];
+							// TODO: Spring?
+							IValidatorContext _context = new ValidatorContext (key, source);
+							okay = table.Format (_context);
+							if (okay)
+								// set to field buffer
+								fields [key] = _context.Target;
+						}
+						break;
+					}
+				}
+
+				if ((have) && (!okay))
+					context.AddAlertForField (key);
+
+			} // end while		
+		}
+
+		#endregion
+
+		#region ProcessRequired
+
+		public void AssertProcessRequired (IRequestContext context)
+		{
+			IDictionary criteria = context.Criteria;
+			if (null == criteria)
+				throw new ArgumentNullException ("Criteria", "BaseValidator.NexusExecute.AssertProcessRequired");
+		}
+
+		public virtual void ProcessRequired (IRequestContext context, bool mode)
+		{
+			IList requiredIDs = context.CommandBin.RequiredIDs; // inner list
+			if (requiredIDs == null) return;
+
+			IList runtimeIDs = context.CommandBin.RuntimeIDs; // inner list
+			if (runtimeIDs != null)
+			{
+				IEnumerator runtime = runtimeIDs.GetEnumerator ();
+				while (runtime.MoveNext ())
+				{
+					string id = runtime.Current as string;
+					requiredIDs.Remove (id);
+				}
+			}
+
+			IEnumerator required = requiredIDs.GetEnumerator ();
+			while (required.MoveNext ())
+			{
+				string id = required.Current as string;
+				bool okay = (context.Contains (id) && (null != context [id]) && (!String.Empty.Equals (context [id].ToString ())));
+				if (!okay)
+				{
+					string message = context.FormatTemplate (Template, id);
+					context.AddAlert (message, id);
+				}
+			}
+		}
+
+		#endregion 
+
+		public override bool RequestExecute (IRequestContext context)
+		{
+			ProcessRelated (context, Mode);
+			ProcessRequired (context, Mode);
+			if (Continue) return CONTINUE;
+			return context.HasAlerts;
+		}
+
+	}
+}
\ No newline at end of file

Added: struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ValidatorContext.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ValidatorContext.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ValidatorContext.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Core/Validators/ValidatorContext.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,42 @@
+using Agility.Core;
+using Nexus.Core.Validators;
+
+namespace Agility.Nexus.Validators
+{
+	/// <summary>
+	/// Concrete IValidatorContext implementation.
+	/// </summary>
+	public class ValidatorContext : Context, IValidatorContext
+	{
+		public ValidatorContext ()
+		{
+		}
+
+		public ValidatorContext (string key, object source)
+		{
+			FieldKey = key;
+			Source = source;
+		}
+
+		private const string _FieldKey = "_FieldKey";
+		public string FieldKey
+		{
+			get { return this [_FieldKey] as string; }
+			set { this [_FieldKey] = value; }
+		}
+
+		private const string _Source = "_Source";
+		public object Source
+		{
+			get { return this [_Source]; }
+			set { this [_Source] = value; }
+		}
+
+		private const string _Target = "_Target";
+		public object Target
+		{
+			get { return this [_Target]; }
+			set { this [_Target] = value; }
+		}
+	}
+}
\ No newline at end of file

Modified: struts/sandbox/trunk/overdrive/Nexus/Extras/Spring/Catalog.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Extras/Spring/Catalog.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Extras/Spring/Catalog.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Extras/Spring/Catalog.cs Wed Jun 15 09:23:51 2005
@@ -23,12 +23,27 @@
 namespace Nexus.Extras.Spring
 {
 	/// <summary>
-	/// Concrete IRequestCatalog implementation 
+	/// Implement IRequestCatalog  
 	/// using Spring as an IOC container [OVR-8].
 	/// </summary>
 	/// 
 	public class Catalog : IRequestCatalog, IApplicationContextAware
 	{
+
+		#region Messages 
+
+		private const string msg_ADD_COMMAND = "This catalog instance is created through dependency injection.";
+		private const string msg_MISSING = "Object is not found in Factory.";
+		private const string msg_NAME = "name";
+		private const string msg_NULL = "Command name cannot be null.";
+		private const string msg_TYPE = "Command is not a IRequestCommand or IRequestChain.";
+		private const string msg_CATALOG_CONTEXT_NULL = "Catalog: Context cannot be null!";
+		private const string msg_CATALOG_COMMAND_NULL = "Catalog: Command within Context cannot be null! -- Was Context retrieved from Catalog?";
+
+		#endregion
+
+		#region IApplicationContextAware 
+
 		private IApplicationContext _Factory = null;
 
 		public IApplicationContext ApplicationContext
@@ -37,37 +52,45 @@
 			set { _Factory = value; }
 		}
 
-		public Catalog ()
-		{
-		}
-
-		public Catalog (IApplicationContext value)
-		{
-			ApplicationContext = value;
-		}
-
-		public IApplicationContext Factory ()
-		{
-			return _Factory;
-		}
-
-		private static string msg_NAME = "name";
-		private static string msg_NULL = "Command name cannot be null.";
-		private static string msg_MISSING = "Object is not found in Factory.";
-		private string msg_TYPE = "Command is not a IRequestCommand or IRequestChain.";
-
-		public object GetObject (string name)
+		/// <summary>
+		/// Allow safe access to Factory.GetObject.
+		/// </summary>
+		/// <param name="name">ID for object</param>
+		/// <returns>Object instance</returns>
+		/// <exception cref="Exception">
+		/// Throws Exception if name is null.
+		/// </exception>
+		private object GetObject (string name)
 		{
 			if (null == name)
-				throw new ArgumentNullException (msg_NAME, "ICatalog.GetObject");
+				throw new ArgumentNullException (msg_NAME, "Nexus.Extras.Spring.Catalog.GetObject");
 			return Factory ().GetObject (name);
 		}
 
+		#endregion
+
+		#region ICatalog
+
+		/// <summary>
+		/// Not implemented as Catalog is expected to be created by an IOC framework.
+		/// </summary>
+		/// <param name="name">ID for command</param>
+		/// <param name="command">Command instance</param>
 		public void AddCommand (string name, ICommand command)
 		{
-			throw new NotImplementedException ();
+			throw new NotImplementedException (msg_ADD_COMMAND); // OK
 		}
 
+		/// <summary>
+		/// Obtain Command and verify that instance is a IRequestCommand.
+		/// </summary>
+		/// <param name="name">Command ID</param>
+		/// <returns>IRequestCommand instance for name</returns>
+		/// <exception cref="Exception">
+		/// Throws Exception if name is null, 
+		/// name is not in catalog, 
+		/// or if instance for name is not a IRequestCommand
+		/// </exception>
 		public ICommand GetCommand (string name)
 		{
 			if (null == name)
@@ -92,37 +115,75 @@
 
 		public IEnumerator GetNames ()
 		{
-			throw new NotImplementedException ();
+			string[] names = _Factory.GetObjectDefinitionNames ();
+			IEnumerator enu = names.GetEnumerator ();
+			return enu;
+		}
+
+		#endregion
+
+		#region IRequestCatalog
+
+		/// <summary>
+		/// Default constructor.
+		/// </summary>
+		public Catalog ()
+		{
 		}
 
-		public IRequestContext GetContext (IRequestCommand command)
+		/// <summary>
+		/// Construct object and set ApplicationContext.
+		/// </summary>
+		/// <param name="value">Our ApplicationContext</param>
+		public Catalog (IApplicationContext value)
 		{
-			IRequestContext context = null;
-			try
-			{
-				context = command.NewContext ();
-				context [Tokens.CommandBin] = command;
-				context [Tokens.FieldTable] = GetFieldTable ();
-			}
-			catch (Exception e)
-			{
-				context = new RequestContext ();
-				context.Fault = e;
-				// ISSUE: Log exception(faults) (Log all errors in verbose mode?)
-				// ISSUE: Provide an alternate location on fault? -- Declarative exception handing
-			}
-			return context;
+			ApplicationContext = value;
+		}
+
+		/// <summary>
+		/// Provide the IApplicationContext instance.
+		/// </summary>
+		/// <returns>IApplicationContext instance</returns>
+		public IApplicationContext Factory ()
+		{
+			return _Factory;
+		}
+
+
+		/// <summary>
+		/// Field for GetFieldTable method.
+		/// </summary>
+		/// 
+		private IFieldTable _FieldTable = null;
 
+		/// <summary>
+		/// Access method for the Catalog's FieldTable.
+		/// </summary>
+		/// <returns>FieldTable for this Catalog</returns></returns>
+		/// 
+		private IFieldTable GetFieldTable ()
+		{
+			if (_FieldTable == null)
+				_FieldTable = GetObject (Tokens.FIELD_TABLE_ID) as IFieldTable;
+			return _FieldTable;
 		}
 
-		public IRequestContext GetContext (string name)
+		public IRequestContext GetRequest (string command)
+		{
+			ICommand _command = GetCommand(command);
+			IRequestCommand _rc = _command as IRequestCommand;
+			return GetRequest(_rc);
+		}
+		
+		public IRequestContext GetRequest (IRequestCommand command)
 		{
 			IRequestContext context = null;
 			try
 			{
-				IRequestCommand command = GetCommand (name) as IRequestCommand;
 				context = command.NewContext ();
 				context [Tokens.CommandBin] = command;
+				context [Tokens.FieldTable] = GetFieldTable ();
+				// TODO: MessageTable
 			}
 			catch (Exception e)
 			{
@@ -132,42 +193,50 @@
 				// ISSUE: Provide an alternate location on fault? -- Declarative exception handing
 			}
 			return context;
+
 		}
 
-		/// <summary>
-		/// Field for GetFieldTable method.
-		/// </summary>
-		/// 
-		private IFieldTable _FieldTable = null;
+		public IRequestContext GetRequest(string command, IDictionary input) {
+
+			IRequestContext context = GetRequest(command);
+			context.Criteria = input;
+			return context;			
+		}	
 
 		/// <summary>
-		/// Access method for the Catalog's FieldTable.
+		/// Confirm that the Context is not null, and the Context's Command is not null.
 		/// </summary>
-		/// <returns>FieldTable for this Catalog</returns></returns>
-		/// 
-		public IFieldTable GetFieldTable ()
-		{
-			if (_FieldTable == null)
-				_FieldTable = GetObject (Tokens.FieldTable) as IFieldTable;
-			return _FieldTable;
-		}
-
-		public void Execute (IRequestContext context)
+		/// <param name="context">IRequestContext to verify</param>
+		/// <returns>The non-null Command for this Context</returns>
+		private IRequestCommand VerifyRequest(IRequestContext context)
 		{
 			if (null == context)
 			{
 				context = new RequestContext ();
-				// ISSUE: Add a message about null context
+				context.AddAlert (msg_CATALOG_CONTEXT_NULL);
 			}
 
 			IRequestCommand command = context [Tokens.CommandBin] as IRequestCommand;
 
 			if (null == command)
 			{
-				// ISSUE: Add a message about null command.
-				// (A null context with then have two messages.)
-			}
-			else
+				context.AddAlert (msg_CATALOG_COMMAND_NULL);
+			}			
+
+			return command;
+		}
+
+		public IRequestContext ExecuteRequest (string command)
+		{
+			IRequestContext context = GetRequest(command);
+			ExecuteRequest(context);
+			return context;
+		}
+
+		public void ExecuteRequest (IRequestContext context)
+		{			
+			IRequestCommand command = VerifyRequest(context);
+			if (context.IsNominal)
 			{
 				try
 				{
@@ -178,34 +247,31 @@
 					context.Fault = e;
 				}
 			}
+
 			// ISSUE: Log exception(faults) (Log all errors in verbose mode?)
 			// ISSUE: Provide an alternate location on fault? -- Declarative exception handing?
 		}
 
-		public IRequestContext ExecuteContext (string command)
-		{
-			IRequestContext context = GetContext (command);
-			Execute (context);
-			return context;
-		}
-
 		public void ExecuteView (IRequestContext context)
 		{
-			IRequestCommand command = context [Tokens.CommandBin] as IRequestCommand;
-			IChain chain = new Chain ();
-			chain.AddCommand (GetCommand (Tokens.PRE_OP));
-			chain.AddCommand (command);
-			chain.AddCommand (GetCommand (Tokens.POST_OP));
-			try
-			{
-				chain.Execute (context);
-			}
-			catch (Exception e)
-			{
-				context.Fault = e;
+			IRequestCommand command = VerifyRequest(context);
+			if (context.IsNominal) {
+				IChain chain = new Chain ();
+				chain.AddCommand (GetCommand (Tokens.PRE_OP_ID));
+				chain.AddCommand (command);
+				chain.AddCommand (GetCommand (Tokens.POST_OP_ID));
+				try
+				{
+					chain.Execute (context);
+				}
+				catch (Exception e)
+				{
+					context.Fault = e;
+				}
 			}
 		}
 
+		#endregion
 
 	}
 }

Added: struts/sandbox/trunk/overdrive/Nexus/Test/Commands/ObjectByKey.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/Commands/ObjectByKey.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/Commands/ObjectByKey.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/Commands/ObjectByKey.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,30 @@
+using System;
+using Nexus.Core;
+
+namespace Nexus.Core.Commands
+{
+	/// <summary>
+	/// Sample model command that adds a result object into the context 
+	/// if the correct key is passed.
+	/// </summary>
+	public class ObjectByKey : RequestCommand
+	{
+		public const string PK_SOMETHING = "pk_something";
+		public const string PK_SOMETHING_VALUE = "12345678-1234-1234-1234-123456789ABC";
+		public const string PK_SOMETHING_RESULT = "SomethingResult";
+		public const string PK_SOME_DATE = "SomeDate";
+
+		public override bool RequestExecute (IRequestContext context)
+		{
+			string value = context [PK_SOMETHING] as string;
+			// IList list = Mapper.Get ().QueryForObject (ID, key);
+			if (PK_SOMETHING_VALUE.Equals (value))
+			{
+				context [PK_SOMETHING_RESULT] = PK_SOMETHING_RESULT;
+				context [PK_SOME_DATE] = DateTime.Now;
+			}
+			return CONTINUE;
+		}
+
+	}
+}
\ No newline at end of file

Modified: struts/sandbox/trunk/overdrive/Nexus/Test/ControllerTest.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/ControllerTest.cs?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/ControllerTest.cs (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/ControllerTest.cs Wed Jun 15 09:23:51 2005
@@ -30,9 +30,9 @@
 		/// </summary>
 		/// 
 		[Test]
-		public void ExecuteContext ()
+		public void ExecuteRequest ()
 		{
-			IRequestContext context = catalog.ExecuteContext (ListAll.LIST_ALL);
+			IRequestContext context = catalog.ExecuteRequest(ListAll.LIST_ALL);
 			AssertNominal (context);
 			Assert.IsTrue (context.IsNominal, "Expected nominal result.");
 			Assert.IsTrue (context.HasOutcome, "Expected outcome from command.");

Added: struts/sandbox/trunk/overdrive/Nexus/Test/ObjectByKeyTest.cs
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/ObjectByKeyTest.cs?rev=190773&view=auto
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/ObjectByKeyTest.cs (added)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/ObjectByKeyTest.cs Wed Jun 15 09:23:51 2005
@@ -0,0 +1,136 @@
+using System;
+using System.Collections;
+using Nexus.Core.Commands;
+using NUnit.Framework;
+
+namespace Nexus.Core
+{
+	/// <summary>
+	/// Prove that a single object can be returned by Execute, without error.
+	/// </summary>
+	[TestFixture]
+	public class ObjectByKeyTest : BaseNexusTest
+	{
+
+		public const string OBJECT_BY_KEY = "ObjectByKey";
+		public const string OBJECT_BY_KEY_WITH_VALIDATE = "ObjectByKeyWithValidate";
+		public const string OBJECT_BY_KEY_WITH_REQUIRED = "ObjectByKeyWithRequired";
+		
+		private string PK_SOMETHING = ObjectByKey.PK_SOMETHING;
+		private string PK_SOMETHING_VALUE = ObjectByKey.PK_SOMETHING_VALUE;
+		private const string PK_SOMETHING_RESULT = ObjectByKey.PK_SOMETHING_RESULT;
+		private const string PK_SOME_DATE = ObjectByKey.PK_SOME_DATE;
+
+		public void AssertSomething (IRequestContext context)
+		{
+			AssertNominal (context);
+			Assert.IsNotNull (context [PK_SOMETHING_RESULT], "Expected result");
+			Assert.IsFalse (context.HasOutcome, "Unexpected Outcome.");
+		}
+
+		public void AssertInvalid (IRequestContext context)
+		{
+			AssertNoFault (context);
+			Assert.IsTrue (context.HasAlerts, "Expected error");
+			Assert.IsNull (context [PK_SOMETHING_RESULT], "Unexpected result");
+			Assert.IsFalse (context.HasOutcome, "Unexpected Outcome.");
+		}
+
+		[Test]
+		public void ObjectByKey_Trusted ()
+		{
+			IRequestContext context = catalog.GetRequest (OBJECT_BY_KEY);
+			context [PK_SOMETHING] = PK_SOMETHING_VALUE;
+
+			catalog.ExecuteRequest (context); // do the actual work
+
+			AssertSomething (context);
+		}
+
+		[Test]
+		public void ObjectByKey_UnTrusted ()
+		{
+			IDictionary fields = new Hashtable ();
+			fields [PK_SOMETHING] = PK_SOMETHING_VALUE;
+			IRequestContext context = catalog.GetRequest (OBJECT_BY_KEY_WITH_REQUIRED, fields);
+
+			catalog.ExecuteRequest (context); // do the actual work
+
+			AssertSomething (context);
+		}
+
+		[Test]
+		public void ObjectByKey_UnTrusted_Fail ()
+		{
+			IDictionary fields = new Hashtable();
+			IRequestContext context = catalog.GetRequest (OBJECT_BY_KEY_WITH_REQUIRED, fields);
+
+			catalog.ExecuteRequest (context); // do the actual work
+
+			AssertInvalid (context);
+		}
+
+
+		[Test]
+		public void ObjectByKey_Validate ()
+		{
+			IDictionary fields = new Hashtable ();
+			fields [PK_SOMETHING] = PK_SOMETHING_VALUE;
+			// fields [PK_SOME_DATE] = DateTime.Now.ToShortDateString ();
+			IRequestContext context = catalog.GetRequest (OBJECT_BY_KEY_WITH_VALIDATE, fields);
+
+			catalog.ExecuteRequest (context); // do the actual work
+
+			AssertSomething (context);
+
+			try
+			{
+				DateTime output = (DateTime) context [PK_SOME_DATE];
+				output = output;
+			}
+			catch (Exception e)
+			{
+				Assert.IsTrue (e != null);
+				Assert.Fail ("Expected date as binary in the main context");
+			}
+
+			string shortDate = context.Criteria [PK_SOME_DATE] as string;
+			Assert.IsNotNull (shortDate, "Expected date as a string in criteria");
+
+			DateTime now = DateTime.Now;
+			// http://www.microsoft.com/globaldev/getWR/steps/wrg_date.mspx
+			// Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+			string expect = now.ToString ("d");
+			Assert.AreEqual (expect, shortDate);
+		}
+
+		[Test]
+		public void ObjectByKey_Format_Date ()
+		{
+			IDictionary fields = new Hashtable();
+			fields [PK_SOMETHING] = PK_SOMETHING_VALUE;
+			fields [PK_SOME_DATE] = DateTime.Now.ToShortDateString ();
+			IRequestContext context = catalog.GetRequest (OBJECT_BY_KEY_WITH_VALIDATE, fields);
+
+			catalog.ExecuteRequest (context); // do the actual work
+
+			AssertSomething (context);
+
+			try
+			{
+				DateTime output = (DateTime) context [PK_SOME_DATE];
+				output = output;
+			}
+			catch (Exception e)
+			{
+				Assert.IsTrue (e != null);
+				Assert.Fail ("Expected date as binary in the main context");
+			}
+
+			string formatted = context.Criteria [PK_SOME_DATE] as string;
+			Assert.IsNotNull (formatted, "Expected date as a string in criteria");
+		}
+
+
+	}
+}
\ No newline at end of file

Modified: struts/sandbox/trunk/overdrive/Nexus/Test/Objects.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/Objects.xml?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/Objects.xml (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/Objects.xml Wed Jun 15 09:23:51 2005
@@ -5,6 +5,7 @@
 
 	<object id="Base" />
 	
+	<import resource="Resources/Command/AppConfig.xml"/>
 	<import resource="Resources/Command/Catalog.xml"/>
 	
 </objects>

Modified: struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/AppConfig.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/AppConfig.xml?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/AppConfig.xml (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/AppConfig.xml Wed Jun 15 09:23:51 2005
@@ -3,47 +3,70 @@
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 	xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd">
 	
-<!-- catalog commands 
+<!-- catalog commands -->
 	
-  <object id="convert_input" type="Nexus.Validators.ConvertInput">
+  <object id="ConvertInput" type="Nexus.Core.Validators.ConvertInput">
     <property name="ID"><value>ConvertInput</value></property>
     <property name="Template"><value>{0} is required.</value></property>
   </object>
 
-  <object id="format_output" type="Nexus.Validators.FormatOutput">
+  <object id="FormatOutput" type="Nexus.Core.Validators.FormatOutput">
     <property name="ID"><value>FormatOutput</value></property>    
     <property name="Template"><value>{0} is required.</value></property>
   </object>
-  
--->
 
-  <!-- pre-op   
-  <object id="pre-op" type="Nexus.NexusChain, Agility.Nexus">
+  <!-- pre-op -->
+  <object id="pre-op" type="Nexus.Core.RequestChain">
+    <property name="ID"><value>pre-op</value></property>    
 	<property name="AddCommands">
 		<list>
-			<ref object="convert_input"/>
+			<ref object="ConvertInput"/>
 		</list>   
     </property>           
   </object>  
-  -->
 
-  <!-- post-op 
-  <object id="post-op" type="Nexus.NexusChain, Agility.Nexus">
+  <!-- post-op -->
+  <object id="post-op" type="Nexus.Core.RequestChain">
+    <property name="ID"><value>post-op</value></property>    
 	<property name="AddCommands">
 		<list>
-			<ref object="format_output"/>
+			<ref object="FormatOutput"/>
 		</list>   
     </property>           
   </object>
--->
     		
- <!-- Nexus Catalog -->
-
-  <object id="Catalog" type="Nexus.Extras.Spring.Catalog"/>
+ <!-- Catalog 
+  <object id="Catalog" type="Nexus.Extras.Spring.Catalog"/>  
+ -->  
   
-<!-- iBATIS Mapper -->
-  
-  <object id="Mapper" type="IBatisNet.DataMapper.Mapper, IBatisNet.DataMapper" 
-		factory-method="Instance"/> 
-    
+ <!-- FieldTable -->
+ 
+	<object id="FieldTable" type="Nexus.Core.Tables.FieldTable">
+		<property name="Strict"><value>true</value></property>
+		<property name="AddFields">
+			<list>
+				<ref object="pk_something"/> 
+				<ref object="SomeDate"/> 
+				<ref object="SomethingResult"/> 
+			</list>
+		</property>
+	</object>
+	
+<!-- Fields -->
+
+	<object id="pk_something" type="Nexus.Core.Tables.FieldContext">
+		<property name="ID"><value>pk_something</value></property>
+	</object>
+	
+	<object id="SomethingResult" type="Nexus.Core.Tables.FieldContext">
+		<property name="ID"><value>SomethingResult</value></property>
+	</object>
+
+	<object id="SomeDate" type="Nexus.Core.Tables.FieldContext">
+		<property name="ID"><value>SomeDate</value></property>
+		<property name="Alert"><value>{0} must be a valid date</value></property>
+		<property name="DataFormat"><value>d</value></property>
+		<property name="DataTypeName"><value>System.DateTime</value></property>
+	</object>
+	       
 </objects>

Modified: struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/Catalog.xml
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/Catalog.xml?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/Catalog.xml (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/Resources/Command/Catalog.xml Wed Jun 15 09:23:51 2005
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8" ?> 
+<?xml version="1.0" encoding="utf-8" ?> 
 <!DOCTYPE objects PUBLIC "-//SPRING//DTD OBJECT//EN"
   "http://www.springframework.net/dtd/spring-objects.dtd">
 <objects> 
@@ -6,5 +6,42 @@
   <object id="ListAll" type="Nexus.Core.Commands.ListAll, Nexus.Test">
     <property name="ID"><value>ListAll</value></property>  
   </object>
+
+  <object id="ObjectByKey" type="Nexus.Core.Commands.ObjectByKey, Nexus.Test">
+    <property name="ID"><value>ObjectByKey</value></property>
+	<property name="AddRequiredIDs">
+		<list>
+			<value>pk_something</value>
+		</list>
+	 </property>          
+ 	 <property name="AddRelatedIDs">
+		<list>
+			<value>SomeDate</value>
+			<value>SomethingResult</value>
+		</list>
+	 </property>          
+   </object>
+
+  <object id="ObjectByKeyWithRequired" type="Nexus.Core.RequestChain">
+        <property name="ID"><value>ObjectByKeyWithRequired</value></property>
+		<property name="AddCommands">
+			<list>
+				<ref object="ConvertInput"/> 
+				<ref object="ObjectByKey"/> 
+			</list>
+		</property>      
+	</object>
+
+  <object id="ObjectByKeyWithValidate" type="Nexus.Core.RequestChain">
+        <property name="ID"><value>ObjectByKeyWithValidate</value></property>
+		<property name="AddCommands">
+			<list>
+				<ref object="ConvertInput"/> 
+				<ref object="ObjectByKey"/> 
+				<ref object="FormatOutput"/> 
+			</list>
+		</property>      
+	</object>
+
 
 </objects>

Modified: struts/sandbox/trunk/overdrive/Nexus/Test/Test.csproj
URL: http://svn.apache.org/viewcvs/struts/sandbox/trunk/overdrive/Nexus/Test/Test.csproj?rev=190773&r1=190772&r2=190773&view=diff
==============================================================================
--- struts/sandbox/trunk/overdrive/Nexus/Test/Test.csproj (original)
+++ struts/sandbox/trunk/overdrive/Nexus/Test/Test.csproj Wed Jun 15 09:23:51 2005
@@ -125,6 +125,15 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "ObjectByKeyTest.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Objects.xml"
+                    BuildAction = "Content"
+                />
+                <File
                     RelPath = "RequestCommandTest.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -136,6 +145,11 @@
                 />
                 <File
                     RelPath = "Commands\ListAll.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Commands\ObjectByKey.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org