Business Objects and Data Sources > The Business Model > Defining the Business Model with Dynamic Classes

You can create new instances of IlpClass dynamically using the Java API.

The easiest way to define a business model from any Java class is to create business classes as instances of IlpDefaultClass and register related class attributes with IlpDefaultAttribute. For more information, see Business Model API. The best place to put the IlpClass definition is the IlpObject implementation.

Defining a Dynamic Class Using the API

Here is an example taken from the FileObject.java file located in the following sample directory:

<installdir>/samples/datasource/explorer2

where <installdir> is the directory where you have installed JViews TGO.

How to Create a Business Class and Register the Related Class Attributes
    public static IlpDefaultAttribute EXISTS =
      new IlpDefaultAttribute("exists",Boolean.class, true);
    public static IlpDefaultAttribute NAME =
      new IlpDefaultAttribute("name",String.class, true);
    public static IlpDefaultAttribute PARENT =
      new IlpDefaultAttribute("parent",String.class, true);
    public static IlpDefaultAttribute PATH =
      new IlpDefaultAttribute("path",String.class, true);
    public static IlpDefaultAttribute DIRECTORY =
      new IlpDefaultAttribute("directory",Boolean.class, true);
    public static IlpDefaultAttribute HIDDEN =
      new IlpDefaultAttribute("hidden",Boolean.class, true);
    public static IlpDefaultAttribute LASTMODIFIED =
      new IlpDefaultAttribute("lastModified", Long.class, true); 
    public static IlpDefaultAttribute LASTMODIFIEDDATE =
      new IlpDefaultAttribute("lastModifiedDate", Date.class, true);
    public static IlpDefaultAttribute LENGTH =
      new IlpDefaultAttribute("length", Long.class, true);
    public static IlpDefaultAttribute ROOT =
      new IlpDefaultAttribute("root", Boolean.class, true);
 
    protected static IlpDefaultClass ILPCLASS;
      
    static {
    ILPCLASS = new IlpDefaultClass("FileObject") {
      /**
       * This method is called when objects are loaded from XML.
       */
       public IlpObject newInstance(IlpClass ilpClass, Object identifier,
        boolean initializeAttributeValues) {
          return new FileObject((File)identifier,ilpClass);
       }
    };
    ILPCLASS.addAttribute(EXISTS);
    ILPCLASS.addAttribute(NAME);
    ILPCLASS.addAttribute(PARENT);
    ILPCLASS.addAttribute(PATH);
    ILPCLASS.addAttribute(DIRECTORY);
    ILPCLASS.addAttribute(HIDDEN);
    ILPCLASS.addAttribute(LASTMODIFIED); 
    ILPCLASS.addAttribute(LASTMODIFIEDDATE);
    ILPCLASS.addAttribute(LENGTH);
    ILPCLASS.addAttribute(ROOT);      
  }

In this sample code, you have created the IlpClass as an IlpDefaultClass with a specific implementation of the newInstance method. This method is used to create objects read from an XML file. Its implementation depends entirely on the case you have to handle. Note that you do not need to implement the newInstance method if you do not intend to use XML with your IlpClass.

Here the FileObject class uses a File as its identifier with all its content. The IlpClass parameter allows you to subclass IlpClass. The parameter initializeAttributeValues has the same meaning as in the XML format. See Table 3.1, Elements in an XML Data File. Here you do not use that parameter because there are no default attribute values.

The class manager is not aware of this new IlpClass. You have to define a static method called GetIlpClass in your implementation of IlpObject to have that class registered with the class manager automatically.

If your Java classes include attributes, you can write an implementation of IlpObject that will act as a wrapper. This wrapper will delegate methods to the underlying Java object to access its attributes. This implementation of IlpObject is described by an IlpClass.

The main methods to implement are the following:

Extending a Predefined Business Class Using the API

The wrapper class FileObject implements the IlpObject interface directly. You could have built it by extending the IlpDefaultObject class, or by using the IlpAttributeValueHolderSupport. However, both these classes contain the structure to store an arbitrary number of attributes and thus have a footprint. In this example, since the underlying File instance stores all the attributes, there is no need for such a structure.

How to Create a Wrapper for a Java Object
public class FileObject implements IlpObject {

The FileObject class contains the definition of the corresponding IlpClass. The corresponding code is not repeated here.

This class contains a number of attribute members. It wraps a java.io.File and has a file attribute, which is also used as the class identifier. This class also contains an IlpClass attribute which makes it possible to use it with IlpClass instances other than the one it defines (typically subclasses of the one it defines). This class also contains an AttributeValueChangeSupport instance that handles notification of attribute changes.

protected File file;
protected IlpClass ilpClass;
protected IlpAttributeValueChangeSupport support = 
   new IlpAttributeValueChangeSupport(this);

The static method GetIlpClass allows you to register the IlpClass with the class manager automatically. Note that ILPCLASS is a static member.

    public static IlpClass GetIlpClass() {
      return ILPCLASS;
    }

The class has two constructors. The first one is the easiest to use, as it takes only the file to be wrapped as parameter. The second one lets you initialize the ilpClass attribute. It corresponds to the method newInstance(IlpClass ilpClass, Object identifier, boolean initializeAttributeValues) of the IlpClass.

    public FileObject(File file) {
      this.file = file;
      this.ilpClass = GetIlpClass();
    }
 
    public FileObject(File file, IlpClass ilpClass) {
      this.file = file;
      this.ilpClass = ilpClass;
    }

The following methods add or remove listeners to attribute value changes and fire events. They all delegate to the IlpAttributeValueChangeSupport instance.

  public void addAttributeValueListener (AttributeValueListener l) {
    support.addAttributeValueListener(l);
  }
 
  public void removeAttributeValueListener (AttributeValueListener l) {
    support.removeAttributeValueListener(l);
  }
 
  public void fireEvent (AttributeValueEvent ev) {
    support.fireEvent(ev);
  }

The method getAttributeValue retrieves attribute values from the java.io.File object.

public Object getAttributeValue (IlpAttribute attribute) {
    if (attribute == EXISTS) {
      return file.exists()?Boolean.TRUE:Boolean.FALSE;
    }
    if (attribute == NAME) {
      String name = file.getName();
      // for the roots the name may be null, so return the path in this case
      return name != null && name.length() != 0 ?name:file.getPath();
    }
    if (attribute == PARENT) {
      return file.getParent();
    }
    if (attribute == PATH) {
      return file.getPath();
    }
    if (attribute == DIRECTORY) {
      return file.isDirectory()?Boolean.TRUE:Boolean.FALSE;
    }
    if (attribute == HIDDEN) {
      return file.isHidden()?Boolean.TRUE:Boolean.FALSE;
    }
    if (attribute == LASTMODIFIED) {
      return new Long(file.lastModified());
    }
    if (attribute == LASTMODIFIEDDATE) {
      Date date = new Date();
      date.setTime(file.lastModified());
      return date;
    }
    if (attribute == LENGTH) {
      return new Long(file.length());
    }
    if (attribute == ROOT) {
      return file.getParent() == null ?Boolean.TRUE:Boolean.FALSE;
    }
     return null;
  }

Here the method setAttributeValue sets the value for one attribute only and sets off notification about value change.

  public void setAttributeValue (IlpAttribute attribute, Object value) {
    if (attribute == LASTMODIFIED) {
      if (value instanceof Number) {
        file.setLastModified(((Number)value).longValue());
        fireEvent(new AttributeValueEvent(this, LASTMODIFIED));
      } else
        throw new IllegalArgumentException(value+" is not acceptable as value of attribute "+attribute);
    }
     }

The getIdentifier method simply returns the wrapped file. The getIlpClass method returns the corresponding attribute. The getIlpAttributeGroup method also returns the IlpClass. The hasAttributeValue method is delegated to the attribute group.

The initializeDefaultValues method does nothing here. It is invoked to initialize the default values of the attributes and corresponds to the XML attribute initializeDefaultValue. See Table 3.1, Elements in an XML Data File for details.

 public Object getIdentifier() {
    return file;
  }
 
  public IlpClass getIlpClass() {
    return ilpClass;
  }
 
  public IlpAttributeGroup getAttributeGroup () {
    return getIlpClass();
  }
 
  public boolean hasAttributeValue (IlpAttribute a) {
    return getAttributeGroup().hasAttribute(a);
  }
 
  public void initializeDefaultValues() {
    // nothing to do here
  }