ILOG JRules User Guide > Integrating Application Data > Tasks > Using the Dynamic XOM API > Creating Your Own Class Driver

When rules use a dynamic class, the rule engine must know the runtime policy for the class. The runtime policy is provided by a class driver, and includes field getters and setters, and method and constructor bodies. The runtime policy is defined through the following classes:

To create a class driver:

  1. Code an implementation of the IlrClassDriver interface.
  2. Provide a static public method with the following signature:
public static IlrClassDriver create(IlrReflect reflect)
{
  // Do something to create and return the driver.
}
An implementation of a class driver must include a method with this signature, which is invoked by introspection to construct a driver object.

A class driver enables you to implement a dynamic class using any type of class. For example, implementing all the dynamic classes of an application using hash tables. Here is a simple example of a class driver that does not support method invocations but does support a zero-argument constructor.

The following IlrHashObject class defines the root Java class to which all the dynamic classes are mapped.

package ilog.rules.factory;
import ilog.rules.bom.*;
import java.util.*;
 
public class IlrHashObject extends HashMap
{
  private IlrClass clazz;
 
  public IlrHashObject(IlrClass arg)
  {
    super(10);
    clazz = arg;
  }
 
  //------------------------------------------------------------
  // Identification methods
  //------------------------------------------------------------
 
  public boolean equals(Object arg)
  {
    return this == arg;
  }
 
  public int hashCode()
  {
    return System.identityHashCode(this);
  }
 
  public String toString()
  {
    StringBuffer buffer = new StringBuffer(100);
    buffer.append(getXOMClassName());
    buffer.append('@');
    buffer.append(Integer.toHexString(hashCode()));
    return buffer.toString();
  }
 
  //------------------------------------------------------------
  // Utilities
  //------------------------------------------------------------
 
  public IlrClass getXOMClass()
  {
    return this.clazz;
  }
 
  public String getXOMClassName()
  {
    return clazz.getFullyQualifiedName();
  }
};

The following IlrHashDriver class defines the runtime policy for such a virtual class hierarchy.

package ilog.rules.factory;
import ilog.rules.bom.*;
import java.util.*;
 
public class IlrHashDriver implements IlrClassDriver
{
  //------------------------------------------------------------
  // Static classes
  //------------------------------------------------------------
 
  static class DynamicTester implements IlrClassDriver.ClassTester
  {
    IlrClass clazz;
    DynamicTester(IlrClass clazz)
    {
      this.clazz = clazz;
    }
 
    public boolean isInstance(Object object)
    {
      return ((object instanceof IlrHashObject) &&
	      clazz.isAssignableFrom(((IlrHashObject)object).getXOMClass()));
    }
  };
 
  static class Reader implements IlrClassDriver.Reader
  {
    String fieldname;
    Reader(String fieldname)
    {
      this.fieldname = fieldname;
    }
 
    public Object get(Object object)
    {
      return ((IlrHashObject)object).get(fieldname);
    }
  };
 
  static class Writer implements IlrClassDriver.Writer
  {
    String fieldname;
    Writer(String fieldname)
    {
      this.fieldname = fieldname;
    }
 
    public void set(Object object,Object value)
    {
      ((IlrHashObject)object).put(fieldname,value);
    }
  };
 
  static class Constructor implements IlrClassDriver.Constructor
  {
    IlrClass clazz;
    Constructor(IlrClass clazz)
    {
      this.clazz = clazz;
    }
 
    public Object newInstance(Object[] arguments)
    {
      return new IlrHashObject(clazz);
    }
  };
 
  static class UnknownChecker implements IlrClassDriver.UnknownChecker
  {
    String fieldname;
      
    UnknownChecker(String fieldname)
    {
      this.fieldname = fieldname;
    }
 
    public boolean isUnknown(Object object)
    {
      return !((IlrHashObject)object).containsKey(fieldname);
    }
  };
 
  //------------------------------------------------------------
  // Implementation of the driver
  //------------------------------------------------------------
 
  public IlrHashDriver()
  {
  }
 
  public static IlrClassDriver create(IlrReflect reflect) throws Exception
  {
    return new IlrHashDriver();
  }
 
  public Class getRootClass()
  {
    return IlrHashObject.class;
  }
 
  public IlrClass getXOMClass(Object object)
  {
    return (object instanceof IlrHashObject) ?
      ((IlrHashObject)object).getXOMClass() : null;
  }
 
  public IlrClassDriver.ClassTester getTester(IlrClass aclass)
  {
    return new DynamicTester(aclass);
  }
 
  public IlrClassDriver.Reader getReader(IlrAttribute attribute)
  {
    return new Reader(attribute.getName());
  }
 
  public IlrClassDriver.Writer getWriter(IlrAttribute attribute)
  {
    return new Writer(attribute.getName());
  }
 
  public IlrClassDriver.UnknownChecker getUnknownChecker(IlrAttribute att)
  {
    return new UnknownChecker(att.getName());
  }
 
  public IlrClassDriver.Invoker getInvoker(IlrMethod method)
  {
    return null;
  }
 
  public IlrClassDriver.Constructor getConstructor(IlrConstructor constructor)
  {
    return new Constructor(constructor.getDeclaringClass());
  }
};

Note
IlrHashObject is not required to implement any interfaces imposed by ILOG JRules.

Suppose that a dynamic class Person with fields name and age are defined, and that the class has the property set indicating that it uses IlrHashDriver as a class driver. The IlrReflect object will contain an instance of IlrClass, named myclass, which represents the dynamic class. The following code creates and adds a Java object that will be seen by the rule engine as belonging to the class Person.

IlrClass myclass = myModel.getClass("mypackage.Person")
IlrHashObject obj = new IlrHashObject(myclass); // Creates the object.
obj.put("name","Michael"); // Initializes the field name.
obj.put("age",new Integer(36)); // Initializes the field age.
context.insert(obj); // Inserts the object.

Note
It is not necessary to create and set the fields in a way that depends on the implementation. Once the class drivers are defined, the dynamic classes provide the means for creating and manipulating objects without knowing the implementation details of a particular driver.

Related Concepts

XML Binding
Web Service Binding

Related Tasks

Creating a Dynamic Class
Writing a XOM using Java-Like Syntax
Invoking Dynamic Classes
Setting the Classpath to Contain the XOM and the Rule Engine
Writing a Ruleset Execution Method