Basket Example (Controlling when a method can be called)

Note: This example (AccessTest.cs) can be found in 'JetfireCoreExampleTests' project, which is part of the release download.

In Jetfire methods are equivlent to commands and properties to information. It is desirable to control when commands are allowed to execute and when information can be viewed or changed. To accomplish this Jetfire can use the 'states' construct or the 'access' construct or a combination of the two. This example focuses on the 'access' programming construct.

With 'access' construct access modifiers can be dynamic. That is a method's or property's access modifier (whether it is private or public) can be changed programmatically. The 'access' construct can use roles (Request Approval example) or the value of a boolean property (this example).

In the following Jetfire code a 'Basket' workflow supports a single command, 'Add'. The 'Add' method is public until the 'Basket' is full. In this example the 'Basket' is full when it has 3 items in it. When that occurs the "Add" method is private. This supports a generic user interface where the interface can simply remove or grey out the 'Add' command when the 'Basket' is full.
Note: This code can be found in 'JetfireCoreExampleTests' project, which is part of the release download.
 # region Jetfire Basket Code
            string jetfireCode =
                @"
            namespace test
            {
               public workflow Basket
               {
                  // Constructor
                  public Basket(string basketName)
                  {
                     // use the built in description properties to store extra information.
                    this.Subject = basketName;
                     
                  }
                  private bool isNotFull = true;
                  //
                  // Returns true when Basket is not full.
                  //
                  public bool IsNotFull
                  {
                      get{return isNotFull;}
                      private set{ isNotFull = value;}
                  }
                  private List list = new List();
                  public void Add(string item)
                    : access(IsNotFull)
                  {
                     list.Add(item);
                     // restrict the size of the basket to 3.
                     if(list.Count >= 3) IsNotFull = false;
                  }
                  
               }
            }
            ";
            #endregion


     /// <summary>
        /// In Jetfire methods are equivalent to commands and 
        /// properties to information. It is desirable to 
        /// control when commands are allowed to execute and 
        /// when information can be viewed or changed. 
        /// 
        /// To accomplish this Jetfire uses the 'access' programming
        /// construct. With this construct access modifiers can be dynamic. 
        /// That is a method's or property's access modifier 
        /// (whether it is private or public) can be changed programmatically.
        /// 
        /// The example uses a 'Basket' workflow which supports a single
        /// command, 'Add'.  The 'Add' method is public until the 'Basket' is full.
        /// In this example the 'Basket' is full when it has 3 items in it.
        /// </summary>
        [TestMethod]
        public void ProgrammaticAccessModifier()
        {
            
            LinqStartObjects start = JetfireTest.NewNexusServer(
                JetfireTest.CDRIVE_JETFIRETEST,     // directory name - where the objects are stored
                TjServerStorageType.FileLinq, 
                TjStorageCommand.ClearStorage       // deletes any existing files in the directory
                );
            TjNexus nexus = start.ClientNexus;
            //
            //  Parse source code and create the Jetfire executable code expressions, 
            //  get the workflow class 'Data',
            //  then instantiate a new workflow object.
            //
            nexus.ParseServer(jetfireCode);
            TjWorkflowClass workflowClass = nexus.FindClass<TjWorkflowClass>("test", "Basket");
            TjParameter[] parameters = TjParameter.ConvertToArray(nexus, "My Basket");
            TjWorkflow data = workflowClass.NewWorkflow(parameters);
            //
            // Check to see if the workflow was created properly.
            //
            Assert.AreEqual("My Basket", data.Get<string>("Subject"));
            //
            //  Check the property value
            //
            Assert.AreEqual(true, data.Get<bool>("IsNotFull"));
            //
            //  Get the method Add and check its access modifier.
            //
            TjMethod addMethod = data.GetMember<TjMethod>("Add");
            Assert.AreEqual(TjAccessModifierType.Public, addMethod.AccessModifier);
            //
            //   Add an item to the Basket.  The acccess modifier will still be public.
            //
            data.Execute("Add", TjParameter.ConvertToArray(nexus, "Pencil"));
            Assert.AreEqual(TjAccessModifierType.Public, addMethod.AccessModifier);

            data.Execute("Add", TjParameter.ConvertToArray(nexus, "Paper"));
            Assert.AreEqual(TjAccessModifierType.Public, addMethod.AccessModifier);
            //
            //  Add a 3rd item to the basket.   Now the access modifier for the 
            //  Add method will be private.
            data.Execute("Add", TjParameter.ConvertToArray(nexus, "Eraser"));
            Assert.AreEqual(TjAccessModifierType.Private, addMethod.AccessModifier);
            //
            // Now the 'Add' method is private.  The human interface can prevent
            // the 'Add' method from being executed.   If the method is executed
            // then an exception will occur.
            //
            JetfireTest.AssertNoIncidents(nexus);
            start.Transport.Dispose();
        
}

Last edited Apr 28, 2009 at 7:48 PM by JohnHansen, version 20

Comments

No comments yet.