At this point, the custom condition is ready for use by your business managers. Optionally, however, you could extend the Scenarios module’s grammar expression editor to provide more elegant handling of the new custom condition in the ACC. This process involves two steps:

The next sections in this chapter describe these steps.

For detailed information on options for extending the expression editor for use in the Scenarios module and other ATG products, refer to the next chapter, Configuring the ATG Expression Editor.

Creating an Expression Grammar Definition File

The following sample shows the file astroweb/astroweb-grammar.xml.

 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <?xcl-stylesheet resource="atg/ui/scenario/expression/scenario-grammar.xsl"?>
  <?xcl-stylesheet resource="atg/ui/expreditor/xcl/grammar.xsl"?>
- <!--
This grammar definition supplies the details of how our example's
custom action and custom condition will be treated in the UI.
  -->

<context>
 <!--
 Define the grammar of action "logInfo".  Our intention is to
  constrain both operands to literals, rather than general scenario
  expressions, and to require the logInteger to be unsigned.
  -->
<sequence id="action-logInfo">
 <!--
 Attach an XML template to this grammar node, specifying the
    SDL that it will emit.  This template will generate an <action-name>
    tag inside the enclosing <action> tag, followed by SDL emitted by
    children of this node.

  -->
<xml-template>
  <action-name>logInfo</action-name>
  <apply-xml-templates />
  </xml-template>
  <!--
 Provide a leading token that will show up as a choice in the
    Actions menu of the scenario editor.

  -->
<token>
  <description>Log test data</description>
  </token>
  <!--  include a token describing the string to be logged
  -->
<token>
  <description>with label</description>
  </token>
  <!--  then, a literal supplying the logString parameter
  -->
<literal>
<xml-template>
  <action-param name="logString">
  <constant>
  <apply-xml-templates />
  </constant>
  </action-param>
  </xml-template>
  <required />
  </literal>
  <!--  then a token describing the int to be logged
  -->
  <token>
  <description>and value</description>
  </token>
  <!--
 then, a literal supplying the integer parameter.  The
    <default> tag is required for all non-String literals as it
    determines the data type.

  -->
<literal>
<xml-template>
<action-param name="logInteger">
<constant>
  <apply-xml-templates />
  </constant>
  </action-param>
  </xml-template>
  <unsigned-integer-editor />
  <required />
<default>
  <value type="java.lang.Integer">1</value>
  </default>
  </literal>
  </sequence>
<!--
 Define the grammar of condition "moonPhase".  Note that the id
  of this grammar element is the prefix "condition-", followed by the
  condition name given in scenarioManager.xml.  We would like to
  support the following syntax:

     Moon's phase is (new | waxing | full | waning) (on DATE-EXPR | now)

  The MoonFilter class expects two operands; the first operand is a
  stringified integer relating to the choice of phase (new, waxing,
  ...), while the second is an arbitrary expression of type Date.

  -->
<sequence id="condition-moonPhase">
<!--
 Attach an XML template to this grammar node, specifying the
    SDL that it will emit inside an enclosing <condition> tag.  This
    template says that a <filter operator="moonPhase"> tag should
    enclose all XML generated by children of this grammar node.

  -->
<xml-template>
<filter operator="moonPhase">
  <apply-xml-templates />
  </filter>
  </xml-template>
<!--
 Provide a leading token that will show up as a choice in the
    Conditions menu of the scenario editor.

  -->
<token>
  <description>Moon's phase is</description>
  </token>
<!--
 Provide a choice of tokens for the moon phase, the first
    condition operand.  Each token's <description> governs how it is
    presented in the scenario editor choice list, while each token's
    XML template supplies an SDL fragment defining a constant value,
    to be generated when that token is the current choice.
  -->
<choice>
<!--  (new | waxing | full | waning)
  -->
<token>
  <xml-template>
    <constant type="java.lang.Integer">0</constant>
  </xml-template>
  <description>new</description>
</token>
<token>
  <xml-template>
    <constant type="java.lang.Integer">1</constant>
  </xml-template>
  <description>waxing</description>
</token>
<token>
  <xml-template>
    <constant type="java.lang.Integer">2</constant>
  </xml-template>
  <description>full</description>
</token>
<token>
  <xml-template>
    <constant type="java.lang.Integer">3</constant>
  </xml-template>
  <description>waning</description>
</token>
</choice>
<!--
 Provide a choice of two possible values for the second
    operand of the condition.  The first choice is a token whose
    displayed description is "now", which is a short hand for an SDL
    expression equivalent to "Today's timeAsDate".  The second choice
    is an arbitrary scenario expression of type java.util.Date.

    Note that the "now" choice must come first, because the SDL for
    "now" can match either of the two choices' templates; we want it
    to match the more specific of the two.

  -->
<choice>
<!--  (on DATE-EXPR | now)
  -->
<token>
<!--  now
  -->
 <xml-template>
  <jndi-property>
   <jndi-url>dynamo:/atg/dynamo/service/CurrentDate</jndi-url>
   <property-name>timeAsDate</property-name>
  </jndi-property>
 </xml-template>
 <description>now</description>
<!--  only show the word "now" in the dropdown choice list
  -->
<hidden />
</token>
<sequence>
<!--  on DATE-EXPR
  -->
<token>
  <editor-text>on</editor-text>
<!--  show ellipsis in dropdown choice list only
  -->
  <description>on...</description>
  </token>
  <scenario-expression type="java.util.Date" />
  </sequence>
  </choice>
  </sequence>
  </context>
Extending the Grammar Extension Class

Create an extension of the class atg.ui.scenario.expression.DefaultGrammarExtension that simply identifies how to locate the grammar extension XML file, which in our example is astroweb/astroweb-grammar.xml. The following sample shows the extension created for our custom condition:

package astroweb;

import atg.ui.scenario.expression.*;

public class AstrowebGrammarExtension extends DefaultGrammarExtension
{
  //----------------------------------------
  /**
   * Construct a grammar extension that references our example custom
   * expression grammar definition.
   */
  public AstrowebGrammarExtension()
  {
    // Specify the grammar file.
    super("astroweb.astroweb-grammar");

    // Note: the grammar file is specified with no suffix and with a
    // dot-qualified package name, since it is localized in a
    // ResourceBundle-like way.  If the user's locale is en_US, for
    // instance, the following files will be searched for, in this
    // order:
    //
    //   astroweb/astroweb-grammar_en_US.xml
    //   astroweb/astroweb-grammar_en.xml
    //   astroweb/astroweb-grammar.xml
  }
}
Specifying the Location of the Expression Grammar XML File

The final step is to add a grammar registry entry to the scenarioManager.xml file that specifies the location of the expression grammar XML file. The following sample shows the additions you would make to the scenarioManager.xml file:

<grammar-registry>
   <grammar-extension-file>astroweb.astroweb-grammar
   </grammar-extension-file>
</grammar-registry>

Note that the grammar file is specified with no suffix and with a dot-qualified package name to make localization easier. If the user’s locale is en_US, for instance, the following files will be searched for, in this order:

astroweb/astroweb-grammar_en_US.xml
astroweb/astroweb-grammar_en.xml
astroweb/astroweb-grammar.xml