Solaris WBEM Developer's Guide

Parsing Queries

The javax.wbem.query package contains utility classes that you use to parse WQL queries. The main class is SelectExp, whose constructor takes in a WQL query string. SelectExp parses the string and splits the string into three parts. These parts can be retrieved using their corresponding accessor methods, as shown in the following table.

Query Part 

Accessor Method 

SELECT list 

getSelectList

FROM clause 

getFromClause

WHERE clause 

getWhereClause

The following query, once parsed, has a SELECT list containing PropertyA and PropertyB. The FROM clause contains test_class, and the WHERE clause contains a parse tree of the conditional expression.



select PropertyA, PropertyB from test_class where 
       PropertyA > 20 and PropertyB < 30

SELECT List

The list returned by the getSelectList method for each SelectExp is an instance of the SelectList class. This list specifies properties that must be included in the selected instances, and consists of a list of AttributeExp instances. You can retrieve these AttributeExp instances using the elements method of SelectList. Each attribute denotes the name of a column that maps to a property of a CIMInstance in WQL. The AttributeExp has an apply method that, when passed in a CIMInstance, returns the value of the property that the AttributeExp represents. The SelectList has an apply method that, when passed in a CIMInstance, returns a CIMInstance containing only the properties that the SelectList AttributeExp instances denote.

FROM Clause

Currently, the only non-join expression that is allowed is the FROM clause. An instance of NonJoinExp is returned when the getFromClause method is invoked on SelectExp. The NonJoinExp represents the name of the class on which the selection is performed.

WHERE Clause

The WHERE clause is represented by QueryExp, an abstract class. The concrete subclasses are AndQueryExp, OrQueryExp, NotQueryExp, and BinaryRelQueryExp. Instances of these expressions are combined in the form of a parse tree that represents the original conditional expression.

The interior nodes of this tree consist of AndQueryExp, OrQueryExp, and NotQueryExp instances. These instances represent AND, OR, and NOT expressions. These expressions in turn can consist of other AND, OR, and NOT expressions and binary relations.

The leaf nodes are BinaryRelQueryExp, which represent expressions of the form property operator constant. This form represents a binary relation between a property and a constant value. You retrieve property operator constant using the getLeftValue, getRightValue, and getOperator methods.

Each QueryExp has an apply method that, when passed in a CIMInstance, returns a boolean value. The boolean value is true if the conditional expression represented by the QueryExp is true for the CIMInstance. Otherwise, the boolean value is false.

The QueryExp has two other useful methods, canonizeDOC and canonizeCOD, which are used to simplify conditional expressions for further processing. The canonizeDOC method converts the parse tree from an arbitrary combination of ANDs and ORs to a canonical disjunction of conjunctions form (OR of ANDs). The canonizeCOD method converts the parse tree from an arbitrary combination of ANDs and ORs to canonical conjunction of disjunctions form (AND of ORs). These classes and methods are used by providers that need to filter instances based on input queries.


Note –

Details of these classes can be found in the Javadoc reference pages. See file:/usr/sadm/lib/wbem/doc/index.html.


Writing a Provider That Handles Queries

The following example provider program uses the query APIs to parse the WQL string that was passed to the provider by the execQuery method. This program parses the select expression in the query string, performs a deep enumeration of the class, and iterates through the instances in the enumeration, matching the query expression and select list to each instance. Finally, the program returns a vector containing the enumeration of the instances that match the query string.


Example 5–1 Provider That Handles Queries

/*
 * The execQuery method will support only limited queries 
 * based upon partial key matching. An empty Vector is 
 * returned if no entries are selected by the query.
 *
 * @param  op The CIM object path of the CIM instance to be returned
 * @param  query The CIM query expression
 * @param  ql The CIM query language indicator
 * @param  cc The CIM class reference
 *
 * @return  A vector of CIM object instances
 *
 * @version    1.19 01/26/00
 * @author     Sun Microsystems, Inc.
 */
public CIMInstance[] execQuery(CIMObjectPath op, 
                       String query, 
                       String  ql,
                       CIMClass cc) 
           throws CIMException {

   Vector result = new Vector();
   try {
       SelectExp q = new SelectExp(query);
       SelectList attrs = q.getSelectList();
       NonJoinExp from = (NonJoinExp)q.getFromClause();
       QueryExp where = q.getWhereClause();

       CIMInstance[] v = enumerateInstances(op, false, true, 
                                            true, null, cc);

       // filtering the instances
       for (int i = 0; i < v.length; i++) {
               if ((where == null) || (where.apply(v[i]) == true)) {
                   result.addElement(attrs.apply(v[i]));
                } 
       }
   } catch (Exception e) {
       throw new CIMException(CIMException.CIM_ERR_FAILED, e.toString());
   }
   return (CIMInstance[])result.toArray();
 } // execQuery
}