Entry Assertion Manager Examples

Defining an action

The use of the EAM is not really required for your Apollo Application to work.  As described in the EAM description, the EAM really enhances the maintainability of an application.  First thing that must be done for the EAM is define the actions (AcceptClause) which can be performed on the Broker (seen in yellow in the example).  Then for each action, define what variables are required for that action, what variables should be processed for that action, and their assosciated types (seen in green).

    The EAM determines what Action is being performed on the Broker by determining which of the AcceptClauses are in a valid state.  The first AcceptClause which evaluates successfully will be the assigned state.  Since some AcceptClauses may be subsets of other AcceptClauses the order in which AcceptClauses are evaluated needs to be declared.  This is done by putting the AcceptClauses into a vector (seen in red).  Defining the variables for each action also allows the EAM to convert incoming request variables into their native java types, such in integers or booleans.

Take a peek at a sample file from the demo Site ExpirationBroker.java

 



Handling an action

    When the request comes in to the broker, you would normally have the EAM check the request for correctness (shown in teal).  As the EAM processes the AcceptClauses to determine the appropriate Action, it prints debugging information to it's log channel so you can determine why it chose the action it did.  There is an example later which describes how to subscribe to that log channel and interpret it's results.  If there is no valid Action matching the request, the EAM throws an exception.  Parsing these exceptions is described in another example. 

    If execution continues past evaluation, you know there is a accepted AcceptClause, meaning the system is in a valid state. Now you can just ask the EAM what the Action is (seen in grey), and perform the appropriate action.  You can fetch the variables (seen in olive) you declared for the action from the EAM, and it will convert to the appropriate type for you (Booleans, Ints, Strings).

Take a peek at the sample file from the demo Site ExpirationBroker.java

Fetching Request Variables

    One of the perks of defining the valid states of your broker by defining AcceptClauses, is the EntryAssertionManager will automatically convert your incoming variables to their correct java type.  No more null checking, or parsing ints.  Here some examples:

Ints

    If you declare an incoming variable as an INT, you can easily fetch it later as a primitive using getInt, or as an Object using getInteger.  If you declare the variable as REQUIRED, it will be required that not only that variable be present in the request, but that it be properly convertible to an INT type.

    AcceptClause
    ac.addAcceptClause(AcceptClause.INT,
"VariableName", AcceptClause.REQUIRED);

   
WebRequest:
        i: "15"
        Broker Code:
    int i = EAM.getInt("VariableName"); -> 15
    Integer integer = EAM.getInteger("VariableName"); -> 15

   
WebRequest:
        i: "fifteen"
        EAM Processing:
            The acceptclause "ac" could not be accepted as a valid state since a required variable could not be converted to it's native type, "int".  Another accept clause would be accepted, or the EAM would throw an EntryAssertion exception.
        Broker Code:
        -None- 


    Declaring a variable as OPTIONAL does not require it to exist for the AcceptClause to be accepted.  A flag on the AcceptClause "FailOnOptional" will toggle weather the EAM will fail if the variable exists but cannot be converted to the requested datatype.  The default is that it false, which means it will ignore such errors.

    AcceptClause
        ac.addAcceptClause(AcceptClause.INT,
"VariableName", AcceptClause.OPTIONAL);

   
WebRequest:
             i: "15"
        Broker Code:
        int i = EAM.getInt("VariableName"); -> 15
        Integer integer = EAM.getInteger("VariableName"); -> 15

   
WebRequest:
             i: "fifteen"
        EAM Processing:
                The incoming variable "i" cannot be properly converted to an int.  If the "FailOnOptional" flag is set to true on the AcceptClause, the AcceptClause will fail.  The default state of the FailOnOptional flag is false, in this case the fact that the "i" variable cannot be converted to an int does not effect if the AcceptClause is accepted. 
        Broker Code: (Given that the AcceptClause was accepted)
        int i = EAM.getInt("VariableName"); -> Throws EntryException
        Integer integer = EAM.getInteger("VariableName"); -> Returns null


    If you declare a variable as OPTIONAL, it may be helpful to define a default for this variable.  That means if the variable is not present in the web request, the EAM will return the default value when the variable is queried.  This may be helpful in reducing null checks if you use OPTIONAL variables.

    AcceptClause
        ac.addAcceptClause(AcceptClause.INT,
"VariableName", AcceptClause.OPTIONAL, 15);

   
WebRequest:
            -None-

        Broker Code:
        int i = EAM.getInt("VariableName"); -> 15
        Integer integer = EAM.getInteger("VariableName"); -> 15


Strings

    The not only ints should be declared in AcceptClauses.   Even though EAM won't help too much in converting to the String datatype (variables in the web request are already strings!), strings will often be the Keys which determine which AcceptClause the EntryAssertionManager should choose.  A few things about Strings in AcceptClauses.  If you declare a string as optional, you can supply a default value.  If you declare a variable as STRING, then use getInteger on it, it will parse the string and return an Integer object (if possible).  It will, however, throw a warning on the EAM_DEBUG channel, because you really shouldn't be doing that.  You cannot use getInt on a STRING.

    AcceptClause
        ac.addAcceptClause(AcceptClause.STRING,
"VariableName", AcceptClause.OPTIONAL);

   
WebRequest:
             i: "15"
        Broker Code:
        String s = EAM.getString("VariableName"); -> "15"
        Integer integer = EAM.getInteger("VariableName"); -> 15


Booleans

    Booleans are generally used with HTML Form checkboxes.  Booleans can be in one of two states.  If the variable exists in the web request, the state is true, if it does not, the state is false.  Booleans must always be optional, otherwise they wouldn't work as described above.  Which means you cannot use booleans as Keys for your AcceptClauses.  If you want a html form button to be the key to your AcceptClause, you should define the button name as a STRING, and set it to REQUIRED.

    AcceptClause
        ac.addAcceptClause(AcceptClause.BOOLEAN,
"VariableName", AcceptClause.OPTIONAL);

   
WebRequest:
             i: "Hithere"
        Broker Code:
        boolean b = EAM.getBoolean("VariableName"); -> true
    WebRequest:
             -None-
        Broker Code:
        boolean b = EAM.getBoolean("VariableName"); -> false


Currency, Dates, Localized Dates,  Localized decimals, Localized percentages

    The EntryAssertionManager will also ultimately be able to process localized dates, decimals, currencies and percentages.  This is on the TODO list under the name "EAM Localization Support".  It is tightly coupled with the Template system having internationalization support.  If this stuff interests you, I have a document which describes the internals (and oh, they are so quite clever) of how this stuff will work.


Handling an EAM Assertion Non-Match

    If the EAM does not find a suitable AcceptClause, then it will throw an EntryAssertion.  Usually you don't want this to happen, and it probably means that the browser corrupted the request, the user entered some bogus data, or the user used a modified or hacked client to send the request.  Sometimes it may be appropriate to return the error to the user or return a standard error message.  Simply letting the EntryAssertion travel up the Page tree will display the cause of the EntryAssertion to the user (or the developer).  If you wish to show a canned "error" message (and perhaps dispatch an error to the engineers), you can catch the exception and transfer control to an Error Message node on the tree.  However you may want to give a meaningful error, or a warning to the user.  Perhaps you are using the EAM to confirm that the "age" field is actually a number.  If the "age" field is declared as an Int, the EAM will not allow the system to process the request if the "age" is not a valid integer.  However it would hardly be suitable in this case to show a general error message; a warning really should be given to the user that the "age" field needs to be an integer.  This can be accomplished by catching the EntryAssertion, and querying it for the cause of the failure.  Via getRequiredFailures and getOptionalFailures.  On AcceptClause setFailOnOptional is boolean.

 

Monitoring EAM Activity via The Log Channel

    The EAM Log channel as defined by the LogManager will show exactly how the EntryAssertionManager is processing incoming requests.  This log channel is an excellent channel to monitor while developing an apollo application; and it probably less important to be monitored in a production system.  You may wish to send this channel to STDIO, or some other action so you can monitor it while your application is running.  Here's some sample output from the EAM Channel: