Autonomic Computing Expression Language

This tutorial shows how to use Autonomic Computing Expression Language (ACEL) in your XML document. It takes a user step-by-step through the process of creating an XML document with ACEL expressions, parsing the XML document, and evaluating ACEL expressions contained in the XML document.

Dakshi Agrawal, Research Staff Member, IBM

Dakshi Agrawal is a Research Staff Member at the IBM T. J. Watson Research Center. Dr. Agrawal received a Ph.D. in Electrical Engineering in 1999 from the University of Illinois at Urbana-Champaign (UIUC). He worked as a Visiting Assistant Professor at UIUC before joining the IBM T. J. Watson Research Center. Dr. Agrawal has more than 30 publications in international conferences and journals in the area of digital communication theory, distributed computing systems, and digital security and privacy. View his Web site at http://www.research.ibm.com/people/a/agrawal. Dakshi Agrawal, James Giles, and Kang-Won Lee were core contributors to the development of the Policy Management Toolkit for the IBM Autonomic Computing Initiative, and received an IBM Research Division Award and Invention Achievement Award for this contribution.



James Giles, Assistant Professor, University of Evansville, Indiana

James Giles is an assistant professor of Electrical Engineering/Computer Science at the University of Evansville, Indiana. He was a research staff member at the IBM T. J. Watson Research Center from 2000-2004. Dr. Giles received a Ph.D. in Electrical Engineering in 2000 from the University of Illinois at Urbana-Champaign (UIUC). He has published many technical articles in international conferences and journals in the area of digital communications, networking, distributed computing, and computer security. View his Web site at http://www.research.ibm.com/people/g/gilesjam. Dakshi Agrawal, James Giles, and Kang-Won Lee were core contributors to the development of the Policy Management Toolkit for the IBM Autonomic Computing Initiative, and received an IBM Research Division Award and Invention Achievement Award for this contribution.



Kang-Won Lee, Research Staff Member, IBM

Kang-Won Lee is a Research Staff Member at the IBM T. J. Watson Research Center. He is currently working on policy-based storage area network planning and verification. Dr. Lee received his Ph.D. in Computer Science from the University of Illinois at Urbana-Champaign in 2000. Dr. Lee has published more than 35 technical articles in premier journals and conferences in the area of computer networks, distributed systems, and policy-based systems management. View his Web site at http://www.research.ibm.com/people/k/kangwon. Dakshi Agrawal, James Giles, and Kang-Won Lee were core contributors to the development of the Policy Management Toolkit for the IBM Autonomic Computing Initiative, and received an IBM Research Division Award and Invention Achievement Award for this contribution.



Jorge Lobo, Research Staff Member, IBM

Jorge Lobo is a Research Staff Member at the IBM T. J. Watson Research Center. Prior to joining IBM he was a principal architect at Teltier Technologies. Before Teltier he was a tenured associate professor of Computer Science at the University of Illinois at Chicago and a member of the Network Computing Research Department at Bell Labs. At Teltier he developed a policy server for the availability management of Presence Servers. He also designed and codeveloped PDL, one of the first generic policy languages for network management. Dr. Lobo has more than 50 publications in international journals and conferences in the areas of networks, databases and artificial intelligence. He is co-author of a Massachusetts Institute of Technology (MIT) book on logic programming and is the cofounder and a member of the steering committee for the IEEE Policy Workshop. He has a Ph.D. in Computer Science from the University of Maryland. View his Web site at http://www.research.ibm.com/people/j/jlobo.



28 February 2005

Before you start

About this tutorial

This tutorial shows how to use the Autonomic Computing Expression Language (ACEL), an XML-based expression language, to create an expression, parse it, prepare input for it, and evaluate it. ACEL was originally developed as a part of the Autonomic Computing Policy Language to describe conditions when a policy should be applied to a managed system. To learn more about how policies can be used to manage an IT system, download IBM® Policy Management for Autonomic Computing (PMAC) from alphaWorks. (See Resources for more information.) However, ACEL is applicable in many other contexts such as specifying service level agreements, pricing, scheduling, and provisioning of services. In general, ACEL can be used to specify various types of expressions (numeric expression, Boolean expression, string expression, and so on) in XML documents.

The distinguishing features of ACEL are:

  • ACEL provides a rich set of datatypes and functions, allowing a simple representation of most expressions required for system management.
  • ACEL is a strongly typed language, and its XML schema enforces most of the type constraints. As a result, ACEL expressions can be validated in plain XML editors to allow easy authoring of ACEL expressions.
  • ACEL can be extended by a deployer such that it retains its typed property. Therefore, even the extended ACEL expressions can be validated in a plain XML editor.
  • ACEL includes a comprehensive time zone specification, with date and time values allowing unambiguous treatment of time instances even in the presence of daylight saving time.

Prerequisites

This tutorial is for an intermediate-level software developer who wants to acquire knowledge of how to embed ACEL expressions in XML files and use them for various applications such as business rules and policy management. The prerequisites for taking the tutorial are a basic knowledge of Java programming and a general understanding of XML schema and processing. You can download the examples in this tutorial, the ACEL JAR file, and the companion document ACEL User's Guide , which presents the complete syntax and semantics of the ACEL expressions with examples. See Resources for more information.

To run the examples in this tutorial, you must install the Java Runtime Environment (JRE) Version 1.4.x. See Resources for links to appropriate run-time environments.

The specific examples in the tutorial are written for IBM WebSphere® Studio Application Developer (Application Developer). You can download a trial version of IBM WebSphere Studio Application Developer. Other Java programming environments can be used, but the required steps might be different than those shown in the tutorial.


Understanding ACEL

ACEL datatypes

ACEL provides nine primitive datatypes: Boolean, Short, Integer, Long, Float, Double, String, Calendar, and URI. In addition, it provides two composite datatypes: CompositeData and Collection. The first seven primitive datatypes, respectively, correspond to XML schema datatypes of boolean, short, int, long, float, double, and string. The Calendar datatype is equivalent to the dateTime XML schema datatype except that it allows for a more generic timezone specification. (See the Java TimeZone specifications for more information.) The URI datatype is equivalent the anyURI XML schema datatype. The CompositeData datatype is equivalent to XML schema complex types. The Collection datatype represents an unordered multiset of expressions. Finally, ACEL supports a Reference element that contains a pointer or a handle to an expression defined elsewhere.

ACEL functions

ACEL supports a rich set of functions. In ACEL, the functions are grouped by the return data type of the evaluation result. The following list shows a subset of the supported standard functions supported by ACEL:

  • Numeric functions:
    • Type cast functions (ToInt, ToFloat, ToLong, and so on)
    • Arithmetic operators (Plus, Product, Remainder, Max, Log, Pow, Ceiling, and so on)
    • Calendar field extraction functions (GetDayOfMonth, GetHour, GetYear, and so on)
  • Boolean functions:
    • Type cast function (ToBoolean)
    • Logical functions (And, Or, Not, Xor)
    • Relational functions (Greater, Equal, GreaterEqual, and so on)
    • String matching functions (Begins, Contains, Ends)
    • Calendar comparison functions (IsAfter, IsBefore, IsWithin)
    • Set functions (Belongs)
  • String functions:
    • Type cast functions (ToString)
    • Substring extraction functions (LeftSubstring, RightSubstring, ReplaceSubstring, and so on)
    • Case conversion functions (ToUpper, ToLower)

For a comprehensive list of ACEL functions, refer to the ACEL User's Guide (see Resources.)

ACEL expressions in XML

ACEL expressions have an intuitive form in their XML representation. For example, consider the simple expression (2+3) rendered in ACEL:

<Plus>
   <IntConstant><Value>2</Value></IntConstant>
   <IntConstant><Value>3</Value></IntConstant>
</Plus>

Due to the type constraints imposed by ACEL XML schema, an XML editor (using ACEL XML schema) would flag the following as being in error because ACEL does not allow addition of a number to a string:

<Plus>
   <IntConstant><Value>2</Value></IntConstant>
   <StringConstant><Value>3</Value></StringConstant>
</Plus>

Representing variables in ACEL

Recall that ACEL was originally developed for policy management in the context of autonomic computing. Therefore, ACEL follows certain naming conventions from the autonomic computing architecture. One example is the usage of the term sensor to represent variables, because the value of variables occurring in policies are obtained from the sensors of a managed resource.

In ACEL, the variables, that is, quantities unknown at the time of writing expressions, can be represented by the PropertySensor element. Each PropertySensor element has a type associated with it that is determined at run time from the supplied value. For example, an expression that multiplies a Float constant 3.14159 to the PropertySensordiameter of type Float would be written as:

<Plus>
   <FloatConstant><Value>3.14159</Value></FloatConstant>
   <PropertySensor propertyName="diameter" />
</Plus>

Invoking a callout function in ACEL

In addition to PropertySensor, ACEL also provides an OperationSensor element that can be used to represent a result obtained by calling an external function call. The OperationSensor element is specified by a portType, an operationName, and zero or more arguments. In general, the value of OperationSensor depends on the arguments used to evaluate it. Therefore, it effectively provides the ability to invoke callout functions in ACEL. For example, the following computes the total response time from a Web application server and a database server.

<Plus>
 <OperationSensor portType="webAppServer" operationName="getAverageResponseTime" />
 <OperationSensor portType="databaseServer" operationName="getAverageResponseTime" />
</Plus>

Setting up the ACEL Library

General setup

For the tutorial, we will describe detailed steps for setting up ACEL within Websphere Studio Application Developer (Application Developer). However, for general usage of ACEL, the only setup required is:

  • Obtain the ACEL library package that includes acexpressions.jar and other helper files (see Resources.)
  • Add acexpressions.jar to the classpath

Optionally, the expressions.xsd schema file (obtained from ACEL library package) can be used with an XML editor to enable more efficient creation and editing of expressions in an XML document.

We give detailed steps for adding the library to the classpath in Application Developer in the next topic, Setting up ACEL in Application Developer. These steps are similar for the Eclipse IDE platform, which is freely available from http://eclipse.org . In this tutorial we use many features that Application Developer provides for handling XML and schema files; for example, auto-generation of XML files from a schema, context sensitive code completion, and XML schema validation. See Resources for information on handling XML files in Eclipse.

Outside Application Developer, the steps for modifying the classpath vary depending on the operating system and platform. Most operating systems have a classpath environment variable named CLASSPATH that can be set. In Windows®, this can be accomplished from the command line as:

set CLASSPATH=acexpressions.jar

Alternatively, acexpressions.jar can be added to the classpath when a Java program is executed as in:

java -classpath full-path-to-jar/acexpressions.jar myapplication

Setting up ACEL in Application Developer

We use Application Developer for the tutorial examples. To set up Application for testing and development, perform the following steps (the steps are similar for the free Eclipse platform):

  1. Obtain and install Application Developer (see Resources for more information).
  2. Start Application Developer, using the default workspace location or choosing an alternate location if you prefer. The workspace is where Application Developer stores all of the data, source, and resources for the projects you are developing.
  3. Create a new Java project.
    1. Select File > New > Project....
    2. Select Java in the left pane, and Java Project in the right pane.
    3. Select Next, and type in the name for the project; we will use ACExpressionTutorial.
    4. Finally, with the Use Default flag checked, click Finish.
  4. Add the acexpressions.jar library to the ACExpressionTutorial project.
    1. Select the project by clicking File > Import....
    2. Select File System, and click Next.
    3. In the From Directory text box, browse (or type) the directory name where acexpressions.jar is located.
    4. Click the checkbox next to acexpressions.jar in the right pane and click Finished.
  5. Add the acexpressions.jar library to the Java build path for the project.
    1. Select the project by clicking Project > Properties.
    2. Select Java Build Path in the left pane the Libraries tab in the right pane.
    3. Click Add Jars..., and select the acexpressons.jar library from the list under the project.
    4. Click OK.

    This effectively adds the library to the classpath for use by other classes in the project.

The expression library is now ready for use within the project.

Additional setup in Application Developer

For the tutorial, you should also add the expressions.xsd schema file and the sample code that came with this tutorial to the project by performing the following steps:

  1. Add the expressions.xsd schema file to the project.
    1. Select the project by clicking File > Import....
    2. Select File System, and click Next.
    3. In the From Directory text box, browse (or type) the directory name where expression.xsd is located.
    4. Click the checkbox next to expression.xsd and click Finished.
  2. Add the sample code acelsample.java and SensorLookupImp.java to the project.
    1. Select File > Import....
    2. Select File System, and click Next.
    3. In the From Directory text box, browse (or type) the directory name where the sample code is located.
    4. Click the checkbox next to class files and click Finished.
  3. Make sure the JRE used for the project is Java 1.4 or newer. After installing Java 1.4 on the system if necessary:
    1. In Application Developer, right click on the project.
    2. Select Properties, and then select Java Build Path.
    3. In the Libraries tab, select JRE System Library, and click Edit....
    4. Select New.
    5. Type a name for the JRE Name field (for example, Java14), and type the JRE home directory or browse for it.
    6. Select OK.

    These steps are illustrated in Figure 1.

Figure 1. Changing the JRE in Application Developer
Changing the JRE in Application Developer

Authoring an ACEL expression

Depending on your needs, you can build an XML file containing a single ACEL expression, or you can include one or more ACEL expressions as part of an existing XML file. In the first case, it is possible to automatically generate an XML file containing a single ACEL expression, whereas the second case requires manual modification of the XML file. The next topics provide examples of the two different styles of authoring.

Authoring a single ACEL expression in its own XML document

An easy way to build an XML file containing a single ACEL expression is to autogenerate the XML file from the schema in Application Developer. To do this:

  1. Right-click on the expression.xsd schema file in Application Developer and click Generate > XML file....
  2. Select a name and location for the XML file (we use the default expressions.xml) and click Next. (Note: If you receive an error saying that "a name must be specified for the namespace with prefix:," remove the namespace entry corresponding to xx by clicking on it and then clicking Delete.)
  3. Select the root node for the expression and make any necessary adjustments to the namespace prefixes. As an example, we can construct an expression 2+5, which is constructed with root node Plus. This root node is shown in Figure 2.

    Figure 2. Generating expression XML from schema in Application Developer
    Generating expression XML from schema in Application Developer

  4. After making all adjustments to the form, select Finish. Application Developer creates the expressions.xml file with a root of Plus and with two compatible arguments for the Plus operation as shown below (the arguments of Plus are both PropertySensor, the tag used to define a variable in ACEL):
<?xml version="1.0" encoding="UTF-8"?>
<exp:Plus xmlns:exp="http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2 
 expressions.xsd ">
<exp:PropertySensor propertyName="QName"/>
<exp:PropertySensor propertyName="QName"/>
</exp:Plus>

The two arguments can be changed to <exp:IntegerConstant><Value>2</Value></exp:IntegerConstant> and <exp:IntegerConstant><Value>5</Value></exp:IntegerConstant> by erasing the existing argument and typing the new argument. Alternatively, the Application Developer code-assist feature can be used to select from a list of possible arguments generated from the schema by erasing an argument and typing CTRL-SPACE (that is, holding down the control key and pressing the space key) as shown below:

Figure 3. Expression modification with Application Developer
Expression modification with Application Developer

Another method for changing an argument is using the XML design mode by clicking the Design tab at the bottom of the XML editing window. Then, an argument of Plus can be changed by right-clicking on the argument, clicking on Replace With, and selecting the new argument type.

To see all of the operations available in the ACEL expression language, consult the expressions.xsd schema or the ACEL User's Guide . (See Resources.)

Authoring ACEL expressions as part of another XML document

ACEL expressions are most commonly used as part of a target XML document. The next topics explain how to write ACEL expressions in an XML file in an embedded manner. First, we explain the modifications required in the target XML schema. Then, we explain the modifications required in the target XML file.

Modifications required in the target XML schema document

To embed ACEL expressions in a target XML document, the expression schema must be referenced by the target XML schema and by the target XML document. As an example, consider an application having a condition element whose child can be any boolean-valued expression. The required steps to modify the XML schema are:

  1. Add the expression namespace to the target XML schema by defining a prefix for the expression namespace. For example, to register the namespace http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2 with prefix exp, the following attribute definition is added to the <xsd:schema> element,
    xmlns:exp="http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2"
  2. Import the schema for the ACEL expression language into the target XML schema. This is accomplished by placing an import statement before the first element definition inside the <xsd:schema> tag. The following is an example of an import statement for the ACEL expression schema assuming it is accessible at the relative path URI, expression.xsd:
    <xsd:import schemaLocation="expressions.xsd" 
       namespace="http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2"/>
  3. Define elements in the target XML schema and include elements from the ACEL expression schema in their definition as needed. The global element names (top level elements) from the ACEL expression language must be prefixed with the prefix defined in the first step (for example, exp). For example, if element condition can have a child boolean expression, it would be defined as:
    <xsd:element name="condition">
       <xsd:complexType>
          <xsd:sequence>
             <xsd:element ref="exp:BooleanExpression"/>
          <xsd:sequence>
       </xsd:complexType>
    </xsd:element>

The first two schema steps can be accomplished automatically using the wizard that is started after typing the import as shown in the Figure 4.

Figure 4. Import expression schema into the target schema
Import expression schema into the target schema

Modifications required in the XML document

Now we need to modify the target XML document to include ACEL expressions. For this, the target XML document must also reference the expression schema. The required steps are:

  1. Add the expression namespace to the target XML document by defining a prefix for the expression namespace. For example, to register the namespace http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2 with prefix exp, the following attribute definition is added to any parent or ancestor node of an element taken from the ACEL schema:
    xmlns:exp="http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2"
  2. Add the schema location information by specifying an xsi:schemaLocation attribute for the same node where the prefix is registered. The schema location attribute is a set of namespace and location URI pairs, with both the pairs and the element separated by spaces. For example:
    xsi:schemaLocation="NAMESPACE1 URI1 NAMESPACE2 URI2"

    where NAMESPACE1 is http://org.myorganization.acelexample/namespaces/eventnamespace, URI1 is the relative path sampleEmbed.xsd, NAMESPACE2 is http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2 and URI2 is the relative path expressions.xsd.

These steps for the target XML document can also be accomplished by right-clicking on the root node in the XML outline view, clicking on Edit Schema Information... and then browsing for the ACEL expression schema or typing in the required parameters (see figure 5).

Figure 5. Refer to expression schema in target XML document
Refer to expression schema in target XML document


Expression evaluation and parsing

Example scenario

ACEL was designed to allow easy inclusion of expressions in XML documents in a common way so that tools and libraries could be provided for expression authoring, parsing, and evaluation. The expression language was originally designed for the Autonomic Computing Policy Language, but it is general and, therefore, is applicable for a wide range of uses.

Consider a case where an enterprise retail organization would like to compute discounts for customers at each retail location based on real-time conditions at a location, such as purchase cost for individual items. Furthermore, the enterprise might want to change the formula on a day-to-day or week-to-week basis to account for different promotions.

One way to achieve this goal is using a client-server model where each retail location reports its current conditions to an enterprise server, which computes the discount and returns it. Another option is to push the discount formulas to the retail locations using ACEL so the formulas can be computed locally. This is especially attractive if the sales volumes are high or if the retail locations are not well connected to the enterprise. The latter option is the simple scenario we will use for the tutorial.

Scenario expression

To be more concrete, we assume that the discount formula is based on the individual cost of an item purchased and the quantity of an item purchased. These factors will be combined to determine the discount for the item. The discount formula we consider is a combination of the following two discounts percentages (the scenario just provides an illustration of ACEL use, it is not important to understand the formulas themselves):

  • A first discount that provides a 10% reduction if the item unit cost is more than $100. This discount can be expressed as:
    MIN( 0.10, 0.10 * FLOOR( COST_OF_ITEM / 100 ) )
  • A second discount that provides a 10% reduction if the base cost for the quantity purchased of an item is between $100 and $200, or 20% if the cost for the quantity purchased of an item is more than $200. This can be expressed as:
    MIN( 0.20, 0.10 * FLOOR( COST_OF_ITEM * QUANTITY / 100 ) )

Taking the discounts together, if the COST_OF_ITEM is $125, and the QUANTITY purchased is 6, then the first discount would be 10%, and the second discount would be 20%. Therefore, there would be a 10% discount followed by a 20% discount, or in other words, the price would be 72% of the base price (that is, (100%-10%)*(100%-20%)).

Rearranging the formulas, we can obtain a single formula that gives the fraction of the base price that the customer should pay as a number from 0 to 1.0:

MAX( 0.90, 1.0 - 0.10 * FLOOR( COST_OF_ITEM / 100 ) )  *
              MAX( 0.80, 1.0 - 0.10 * FLOOR( COST_OF_ITEM * QUANTITY / 100) )

Scenario expression encoded as ACEL

In the scenario, the discount formula is wrapped in a DiscountFormula tag, which is in turn wrapped in a WeeklyOperations tag. In a normal application there would typically be additional elements. The XML fragment with the scenario expression encoded as ACEL is as follows (the prefix definition and schema location have been omitted):

<discount:WeeklyOperations>
   <discount:DiscountFormula>
      <exp:Product>

         <!-- Multiplier of 0.9 if COST_OF_ITEM is more than $100, else
         multiplier of 1.0 -->
         
         <exp:Max>
            <exp:DoubleConstant>
               <Value>0.90</Value>
            </exp:DoubleConstant>
            <exp:Minus>
               <exp:DoubleConstant>
                  <Value>1.0</Value>
               </exp:DoubleConstant>
               <exp:Product>
                  <exp:DoubleConstant>
                     <Value>0.10</Value>
                  </exp:DoubleConstant>
                  <exp:Floor>
                     <exp:Division>
                        <exp:PropertySensor propertyName="COST_OF_ITEM" />
                        <exp:DoubleConstant>
                           <Value>100.0</Value>
                        </exp:DoubleConstant>
                     </exp:Division>
                  </exp:Floor>
                </exp:Product>
            </exp:Minus>
         </exp:Max>

         <!-- Multiplier of 0.8 if COST_ITEM*QUANTITY is greater than $200
         or 0.9 if COST_ITEM*QUANTITY is between $100 or $200 or 1.0 else-->
			
         <exp:Max>
            <exp:DoubleConstant>
               <Value>0.80</Value>
            </exp:DoubleConstant>
            <exp:Minus>
               <exp:DoubleConstant>
                  <Value>1.0</Value>
               </exp:DoubleConstant>
               <exp:Product>
                     <exp:DoubleConstant>
                        <Value>0.10</Value>
                     </exp:DoubleConstant>
                     <exp:Floor>
                        <exp:Division>
                           <exp:Product>
                              <exp:PropertySensor 
                                 propertyName="COST_OF_ITEM" />
                              <exp:PropertySensor 
                                 propertyName="QUANTITY" />
                           </exp:Product>
                           <exp:DoubleConstant>
                              <Value>100.0</Value>
                           </exp:DoubleConstant>
                        </exp:Division>
                     </exp:Floor>
               </exp:Product>
            </exp:Minus>
         </exp:Max>
      </exp:Product>
   </discount:DiscountFormula>
</discount:WeeklyOperations>

Note the use of the PropertySensor tag to identify the variables.

Expression parsing

To use an expression, you must first convert it from XML to an internal representation. The ACEL expression library provides an internal representation and facilities for parsing an ACEL expression element. Using an XML parser such as JAXP or the Apache Xerces DOM Parser, the ACEL expression elements can be retrieved from an XML file for further parsing by the ACEL expression library.

The following sample code reads an XML file, performs an XML parse, and retrieves the first XML element that is a Product ACEL expression:

// read the XML document
String fileName = "discountScenario.xml";
InputSource xmlInputSource = null;
try {
   xmlInputSource = new InputSource(new FileReader(fileName));
} catch (FileNotFoundException e) {
   e.printStackTrace(); // File could not be found
}

// obtain a DOM representation of the XML file
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document document = null;
try {
   dbf.setNamespaceAware(true);
   DocumentBuilder db = dbf.newDocumentBuilder();
   document = db.parse(xmlInputSource);
} catch (SAXException e1) {
   e1.printStackTrace();  // XML Parsing error
} catch (IOException e1) {
   e1.printStackTrace();  // Problem with file IO
} catch (ParserConfigurationException e) {
   e.printStackTrace();   // Problem with parser configuration
}

/*
 * Obtain the first ACEL Product element.
 * This step is different for a different XML document 
 * structure. In some instances, it may be necessary to walk
 * the document nodes to find expression nodes of interest.
 * See documentation for the XML parser for more information. 
 *
 */
Element xmlElement =
   (Element) document
   .getElementsByTagNameNS(
   "http://www.ibm.com/namespaces/autonomic/policy/expressions/1.2",
   "Product").item(0);

After obtaining an XML element representation of an ACEL expression, the ExpressionCreator provided by the ACEL library can be used to obtain a java representation of the ACEL expression as follows:

// Parse the ACEL expression
Expression javaExpression = null;
try {
   javaExpression = ExpressionCreator.createExpression(xmlElement);
} catch (ExpressionException e2) {
   //Could not parse the ACEL expression from the given node
   e2.printStackTrace();
}

Preparing input for expression evaluation

After the ACEL expression has been converted to a Java representation, it is possible to evaluate it one or more times with different variable values. The first step is to build a SensorLookup implementation class. The SensorLookup interface is used by the ACEL expression evaluator to obtain variable values as they are needed.

We define a simple SensorLookup backed by a HashMap as follows:

/**
 * Implements sensor lookup to retrieve expression variables for expression evaluation.
 */
public class SensorLookupImp extends HashMap implements SensorLookup {

   /* 
    * @see com.ibm.autonomic.policy.expression.SensorLookup#getSensorValue
    (java.lang.String)
    */
   public Object getSensorValue(String propertyName) {
      return get(propertyName);
   }

   /* 
    * @see com.ibm.autonomic.policy.expression.SensorLookup#getSensorOperation
    (com.ibm.autonomic.policy.expression.SensorOperation)
    */
   public Object getSensorOperation(SensorOperation arg0) {
      throw new UnsupportedOperationException();
   }
}

Next, the new SensorLookupImp is used to store the current values of the variables as follows:

// Prepare SensorLookup
SensorLookupImp s = new SensorLookupImp();
s.put("COST_OF_ITEM", new Double(125));
s.put("QUANTITY", new Integer(6));

The values of the variables can be modified in the SensorLookupImp for future expression evaluations.

Expression evaluation

After parsing the ACEL expression and preparing a SensorLookup, the expression can be evaluated as follows:

// evaluate it
Object result = null;
try {
   result = javaExpression.evaluate(s);
} catch (EvaluationException e3) {
   e3.printStackTrace(); // error in evaluation
}

Assuming no errors have occurred, the object result will hold the value of the expression for the given variable values. In the sample program, the output is as expected; the multiplier is 0.72.

Error codes and exception conditions

The errors that can occur with the ACEL expression library consist of:

  • Errors occurring during XML parsing such as FileNotFoundException, SAXException, and IOException. To correct these errors, try to ensure that the file exists and is a valid XML file.
  • Errors occurring when an ACEL expression is converted from XML representation to Java representation. If the XML is a valid representation of ACEL according to the expression schema, this should not normally happen. To diagnose, try to validate the document using a tool like Application Developer.
  • Errors occurring when an expression is evaluated. When an expression is evaluated, several things can go wrong such as:
    • Illegal operation like division of an integer by zero (for example, 17/0)
    • Evaluation without all of the necessary variables
    • Type incompatibilities between variables and their operators

To correct these errors, it is necessary to change the expression or provide correct variables with correct types.


Summary and resources

Summary

The Autonomic Computing Expression Language (ACEL) lets you create complex expressions in XML documents and provides Java library support to evaluate them. By embedding ACEL expressions in an XML document, users of ACEL have a flexible way to author application-specific rules and to distribute them. ACEL is strongly typed, and the correctness of an expression can be checked by XML editors with a schema validation capability. ACEL also provides a well-defined interface to create new functions. Advanced developers might want to continue to an upcoming tutorial on extending ACEL to create application-specific functions.


Download

DescriptionNameSize
Code sampleac-acelsource.zip368 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Tivoli (service management) on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Tivoli
ArticleID=129345
ArticleTitle=Autonomic Computing Expression Language
publish-date=02282005