Skip Headers

Oracle Internet File System Developer Reference
Release 9.0.1.1.0

Part Number A90093-02
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

6
Applying Arbitrary Metadata and Behavior

This chapter describes how to apply arbitrary metadata and behavior to content types. The chapter covers the following topics:

Applying Arbitrary Metadata and Behavior Overview

The first step in customizing Oracle 9iFS for your business is usually to define all of the physical types of information you wish to store and manage with Oracle 9iFS. Out-of-the-box, Oracle 9iFS manages standard types of information, such as documents and folders. Oracle 9iFS provides out-of-the-box content types (e.g., Document and Folder) that define the physical structure of the information (e.g., Content, Format, Size), and provide interfaces for manipulating the information (e.g., getContent() and listItems()). You can extend these content types to define other physical types of information, such as Image or Book. Chapter 5, "Extending Content Types and Attributes" and Chapter 17, "Customizing Content Type Behavior" discuss how to extend the custom type hierarchy to include attributes and behaviors for different physical types of information.

In defining your business' content types, however, you may find that you also need to manage arbitrary metadata and behaviors that can be applied to your information. The metadata and behaviors are arbitrary in that they may or may not be applied to selected instances of various physical types of information. For example, you might categorize specific instances of different content types into a common metadata structure, such as a subject catalog, according to how they are used in your business. You might define business rules for how certain operations should be performed on various content types, or on specific instances of a content type.

Oracle 9iFS provides the following mechanisms for applying arbitrary metadata and behaviors to your information:

This chapter provides instructions on how to create and apply Categories, PropertyBundles, PolicyPropertyBundles, and Relationships.

Categories

Categories allow you to organize information stored in Oracle 9iFS according to how it is used in your business. For example, you might organize your documents, folders, and images according to the projects that they are used for. By virtue of belonging to the category, you can add extra attributes and behaviors that pertain to that category. For example, you might add the attributes Project Name, and Project Record Number to documents and folders that belong to a Project category.

Oracle 9iFS provides a content type, Category, which you can use to create categorization schemes and apply them to your information. Category is a content type that can be extended to define different types of categories (e.g., Project) and the attributes that pertain to that category (e.g., Project Name, Project Record Number).

A document, folder, or any PublicObject can be associated with zero, one, or more categories. A PublicObject is categorized by associating it with an instance of the extended Category content type. The Category instance stores the values for the extra attributes that pertain to the PublicObject by virtue of it belonging to that category (e.g., Project Name = "Content Management Research Project", Project Record Number = "AR1098a"). The Category instance also stores a pointer to the PublicObject in an attribute AssociatedPublicObject.

Since any PublicObject (e.g., document, folder, image) can be associated with the same category types, categories provide a common scheme for organizing different physical types of information. In a way, categories provide a means for cross-inheriting attributes across different content types.

Because the Category content type extends PublicObject, Category instances can be foldered. This may be useful if you are building a custom user interface and wish to represent documents in different ways in different folders. For example, you could create a Project folder that contain all documents pertaining to a project. Rather than foldering the Document instances and listing them by Name, you could folder the Project category instances and list them by the Project Record Number attribute. You could then allow users to access the Document instance by calling the getAssociatedPublicObject() method on the Category instance.



NOTE:

The out-of-the-box clients in this release of Oracle 9iFS do not support foldering Categories. If you plan to folder Categories, you must implement a custom user interface that allows users to view them. 


Category instances are not versioned by Oracle 9iFS. If a document's category metadata changes with each version, then each document version can be associated with a new Category instance. However, the version information is maintained on the document, not its categories.

Access to Category instances is determined by the AccessControlList applied to the associated PublicObject. If a user has been granted getAttribute() on the PublicObject, he can access the category attributes as well.

Categories are automatically deleted when the associated PublicObject is freed. No notification will be generated when the Category instances are deleted in this manner.

From this section, you will learn how to:

Defining New Category Types

Defining new types of Category entails the same steps required for defining any custom content type. As for any other content type, you create a set of SchemaObject instances to represent the Category type. You can also define custom behavior for the category type by implementing Java classes. However, implementing custom Java classes is not required to define a new category type. Afterwards, you can modify and delete the category type by editing or deleting its SchemaObjects. These development tasks can be done with the Java API, XML files, or the Oracle 9iFS Manager.



NOTE:

For detailed instructions on creating, modifying and deleting custom content types, consult Chapter 5, "Extending Content Types and Attributes"and Chapter 17, "Customizing Content Type Behavior". If you have already read these chapters, this section provides quick review how to create, modify and delete category types with Java and XML. 


Creating Category Types

To create a new type of category, you create a new content type that extends Category and adds attributes that are pertinent to that category. For example, you could create a new category, Project Record, that extends Category and includes the extended attributes Project Name and Project Record Number.

To define the new category type, follow these steps:

Example 6-1 Using XML to Create Category Types

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <NAME>ProjectRecord</NAME>   
    <SUPERCLASS RefType = "Name">Category</SUPERCLASS>  
    <DESCRIPTION>Public Objects that pertain to a Project.</DESCRIPTION>
    <ATTRIBUTES>
        <ATTRIBUTE>
            <NAME>ProjectName</NAME>
            <DATATYPE>String</DATATYPE>
        </ATTRIBUTE>
        <ATTRIBUTE>
            <NAME>ProjectRecordNumber</NAME>
            <DATATYPE>String</DATATYPE>
        </ATTRIBUTE>
    </ATTRIBUTES>
</CLASSOBJECT>


NOTE:

For a description of each element in an XML file used to create category types, consult the Chapter 5, "Extending Content Types and Attributes"


Example 6-2 Using Java to Create Category Types

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
  2. Create a ClassObjectDefinition to hold the values for the ClassObject that represents the category type.

    ClassObjectDefinition codef = new ClassObjectDefinition(session);
    codef.setAttributeByUpperCaseName(ClassObject.NAME_ATTRIBUTE,
         AttributeValue.newAttributeValue("ProjectRecord"));
    
    
  3. Specify that your new category type extends the Category content type.

    ClassObject catco = session.getClassObjectByName("CATEGORY");
    codef.setSuperclass(catco);
    
    
  4. Create AttributeDefinitions for each attribute pertaining to the category type. Add the AttributeDefinitions to the ClassObjectDefinition.

    AttributeDefinition attdef1 = new AttributeDefinition(session);
    attdef1.setAttributeByUpperCaseName(Attribute.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("ProjectName"));
    attdef1.setAttributeByUpperCaseName(Attribute.DATATYPE_ATTRIBUTE,
            AttributeValue.newAttributeValue(Attribute.ATTRIBUTEDATATYPE_STRING));
    
    codef.addAttributeDefinition(attdef1);
    
    AttributeDefinition attdef2 = new AttributeDefinition(session);
    attdef2.setAttributeByUpperCaseName(Attribute.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("ProjectRecordNumber"));
    attdef2.setAttributeByUpperCaseName(Attribute.DATATYPE_ATTRIBUTE,
            AttributeValue.newAttributeValue(Attribute.ATTRIBUTEDATATYPE_STRING));
    
    codef.addAttributeDefinition(attdef2);
    
    
  5. Create the ClassObject and Attributes for the new category type.

    ClassObject mycatco = (ClassObject) session.createSchemaObject(codef);
    

Modifying Category Types

You can add and remove attributes on a category type after it has been created.



NOTE:

You cannot use XML to add or remove attributes from a category type. You must do this with Oracle 9iFS Manager or the Java API. For instructions on deleting attributes with Oracle 9iFS Manager, consult the Oracle 9iFS Setup and Administration Guide


Example 6-3 Using Java to Add, Remove, and Update Attributes on Categories

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
  2. Get the ClassObject that represents the category type.

    ClassObject catco = session.getClassObjectByName("PROJECTRECORD");
    
    
  3. Add an Attribute to the ClassObject.

    AttributeDefinition attdef1 = new AttributeDefinition(session);
    attdef1.setAttributeByUpperCaseName(Attribute.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("ProjectPriority"));
    attdef1.setAttributeByUpperCaseName(Attribute.DATATYPE_ATTRIBUTE,
            AttributeValue.newAttributeValue(Attribute.ATTRIBUTEDATATYPE_INTEGER));
    catco.addAttribute(attdef1);
    
    
  4. Remove an Attribute from the ClassObject.

    Attribute att2 = catco.getEffectiveClassAttributes("PROJECTRECORDNUMBER");
    catco.removeAttribute(att2);
    
    
  5. Update an Attribute on the ClassObject.

    Attribute att3 = catco.getEffectiveClassAttributes("PROJECTPRIORITY");
    Collection vdColl = session.getValueDomainCollection();
    ValueDomain vd = (ValueDomain) vdColl.getItems("Projects");
    att3.setValueDomain(vd);
    

Deleting Category Types

You can use the Java API or Oracle 9iFS Manager to delete category types. If instances exist for the Category, then they must be removed before you can remove the Category type.



NOTE:

For instructions on how to delete the ClassObject for a category type with Oracle 9iFS Manager, consult the Oracle 9iFS Setup and Administration Guide


Example 6-4 Using Java to Delete Categories

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
    
  2. Get the ClassObject that represents the category type.

    ClassObject catco = session.getClassObjectByName("PROJECTRECORD");
    
    
    
  3. Delete the ClassObject by calling the free() method.

    catco.free();
    

Categorizing PublicObjects

Once you have created a new Category type, you can use it to categorize documents, folders, or any PublicObject in Oracle 9iFS. This section describes the following tasks:

Creating Category Instances

To categorize a PublicObject, you create a new instance of your category type and associate it with the PublicObject. You can apply Category instances when creating new PublicObjects, or to PublicObjects that already exist in Oracle 9iFS.

Using Java to Categorize PublicObjects

To categorize a PublicObject with the Java API, follow these steps:

  1. Create a CategoryDefinition to hold the values for the new Category instance.

  2. Specify the type of the new Category instance.

  3. Set the values of the Category's attributes.

  4. If you wish to categorize a PublicObject at the time that it is created in Oracle 9iFS, pass the CategoryDefinition to the addCategoryDefinition() method on the PublicObjectDefinition. The PublicObjectDefinition is used to create both the PublicObject and the Category.

  5. If you wish to categorize a PublicObject that already exists in Oracle 9iFS, pass the CategoryDefinition to the addCategory() method on the PublicObject.

Example 6-5 Using Java to Categorize PublicObjects

  1. Create a new CategoryDefinition.

    CategoryDefinition cdef = new CategoryDefinition(session);
    
    
  2. Specify the type of the new Category instance.

    ClassObject co = session.getClassObjectByName("PROJECTRECORD");
    cdef.setClassObject(co);
    
    
  3. Set the values of the Category's attributes.

    cdef.setAttributeByUpperCaseName(Category.NAME_ATTRIBUTE,
             AttributeValue.newAttributeValue(
               "Content Management Marketing Analysis Report"));
    cdef.setAttributeByUpperCaseName("PROJECTNAME", 
         AttributeValue.newAttributeValue("Content Management Research Project"));
    cdef.setAttributeByUpperCaseName("PROJECTRECORDNUMBER",
         AttributeValue.newAttributeValue("AR1098a"));
    
    
  4. Add the CategoryDefinition to a PublicObjectDefinition to categorize a new PublicObject.

    FolderDefinition fdef = new FolderDefinition(session);
    fdef.setAttributeByUpperCaseName(Folder.NAME_ATTRIBUTE,
         AttributeValue.newAttributeValue("Collateral"));
    fdef.addCategoryDefinition(cdef);
    Folder f = (Folder) session.createPublicObject(fdef);
    
    
  5. Or, use the CategoryDefinition to categorize an existing PublicObject.

    f.addCategory(cdef);
    
Using XML to Categorize PublicObjects

You can also use XML to categorize new PublicObjects. When the XML file is imported into Oracle 9iFS, the IfsSimpleXmlParser automatically parses the file and generate an instance of the category type to hold the category metadata for the PublicObject. The following are the key aspects of an XML file used to categorize a PublicObject:

Example 6-6 Using XML to Categorize New PublicObjects

<?xml version="1.0" standalone="yes"?> 
  <FOLDER> 
    <NAME>CMProject</NAME> 
    <FOLDERPATH>/home/guest</FOLDERPATH> 
    <CATEGORIES> 
      <PROJECTRECORD> 
        <NAME>Content Management Market Analysis</NAME>   
        <PROJECTNAME>Content Management Research Project</PROJECTNAME>
      </PROJECTRECORD> 
      <!-- You can have multiple Category elements here --> 
    </CATEGORIES> 
  </FOLDER> 


NOTE:

For a detailed overview of the syntax rules for XML configuration files, consult Chapter 10, "XML and the Oracle Internet File System"


Updating Category Instances

Once you have categorized a PublicObject, you may need to update the values of the attributes applied to it by the Category instance. You can update a PublicObject's category attributes with either XML configuration files or the Java API.

Using XML to Update Category Instances

To update a Category instance, the XML file must:

Example 6-7 Using XML to Update Attributes on Category Instances

<?xml version="1.0" standalone="yes"?>
<PROJECTRECORD>
    <UPDATE RefType = "Name">Content Management Market Analysis</UPDATE>   
    <PROJECTNAME>XML Research Project</PROJECTNAME>
</PROJECTRECORD>
Using Java to Update Category Instances

You can also update the values of attributes on Category instances with the Oracle 9iFS Java API. Each extended Category type inherits the methods getAttribute() and setAttribute() from the Category class. These methods provide a generic way to manipulate any attribute value.

You can also implement custom Java classes to provide convenience methods for getting and setting the values for the extended attributes on your custom category type. For instructions on implementing custom Java classes, consult Chapter 17, "Customizing Content Type Behavior".

Example 6-8 Using Java to Update Category Instances

  1. Assume that your application has already obtained the Category instance

    Category cat = ......
    
  2. Update the ProjectPriority attribute on the ProjectRecord instance.

    cat.setAttribute("PROJECTPRIORITY", 
                    AttributeValue.newAttributeValue(new Integer(3)));
    

Deleting Category Instances

You can remove PublicObjects from a category by deleting the Category instance that holds the PublicObject's category attribute values. When a PublicObject is deleted, all of its categories are automatically deleted by Oracle 9iFS.

You can delete Category instances with the Oracle 9iFS Java API as you would any other object by calling the free() method. Oracle 9iFS does not support XML as a method for removing PublicObjects from a category, nor does the Oracle 9iFS Manager provide a user interface for deleting Category instances.

Example 6-9 Using Java to delete Category instances

  1. Assume that your application has already obtained the Category instance

    Selector s = new Selector(session);
    s.setSearchClassname("PROJECTRECORD");
    
    LibraryObject[] cats = s.getItems();
    Category c;
    
    
  2. Delete the Category instances.

    int i;
    int count = (cats == null) ? 0 : cats.length;
    
    for (i = 0; i < count; i++)
    {
       c = (Category) cats[i];
       c.free();
    }
    

Searching for Information Based on Categories

Once you have categorized documents, folders, and other types of information, you can search for the information based on its category and category attributes.

For example, you could search for all documents, folders, and other types of information that are project records for the Content Management Research Project. To do this, you would search for all PublicObjects that have been categorized as a Project Record and that have the category attribute Project Name set to Content Management Research Project.

Oracle 9iFS also provides APIs that make it easy to traverse the association between information and their categories. For example, given a PublicObject instance, you can fetch all associated categories. Conversely, given a category instance, you can fetch the associated PublicObject.

Searching for PublicObjects Based on Categories

You can build applications that search for PublicObjects based on their category metadata by constructing a Selector or Search with the Oracle 9iFS Java API. To construct the query, the Search or Selector would join the Category and PublicObject content types based on the reference between the AssociatedPublicObject attribute on Category, and the ID attribute on PublicObject. Then, the Search or Selector can include additional criteria about either the Category and/or PublicObject's attributes.



NOTE:

For detailed instructions on building Selectors and Searches, see Chapter 8, "Building Search Applications"


Example 6-10 Using a Selector to Find Specific Categories on a PublicObject


  1. Assume that your application has already obtained the PublicObject

    PublicObject po = .....
    
    
  2. Construct the Selector.

    Selector s = new Selector(session);
    s.setSearchClassname("PROJECTRECORD");
    s.setSearchSelection("ASSOCIATEDPUBLICOBJECT = " + po.getId() + 
                         " AND PROJECTNAME = 'XML Research Project'");
    
    
  3. Execute the query and retrieve each category for the PublicObject.

    LibraryObject[] cats = s.getItems();
    
    int i;
    int count = (cats == null) ? 0 : cats.length;
    for (i = 0; i < count; i++)
    {
       c = (Category) cats[i];
    }
    

Example 6-11 Using a Search to find all PublicObjects Based on a Common Category Attribute

  1. Construct a SearchSpecification to hold the query criteria. This example does not include content criteria, so we construct an AttributeSearchSpecification.

    AttributeSearchSpecification asp = new AttributeSearchSpecification();
    
    
  2. Construct the SearchClassSpecification and set it on the AttributeSearchSpecification.

    String[] searchClasses = {"PUBLICOBJECT", "PROJECTRECORD"};
    SearchClassSpecification scp = new SearchClassSpecification(searchClasses);
    scp.addResultClass("PUBLICOBJECT");
    
    asp.setSearchClassSpecification(scp);
    
    
  3. Construct a JoinQualification to join the Category type, ProjectRecord, with the PublicObject content type.

    JoinQualification jq = new JoinQualification();
    jq.setLeftAttribute("PUBLICOBJECT", null);
    jq.setRightAttribute("PROJECTRECORD", "ASSOCIATEDPUBLICOBJECT");
    
    
  4. Construct an AttributeQualification to specify the criteria that the category's ProjectName attribute must be "Content Management Research Project".

    AttributeQualification aq = new AttributeQualification();
    aq.setAttribute("PROJECTRECORD", "PROJECTNAME");
    aq.setOperatorType(AttributeQualification.EQUAL);
    aq.setValue("Content Management Research Project");
    
    
  5. Construct a SearchClause to combine the Join and Attribute qualifications, and require that both criteria must be satisfied. Use it to set the SearchQualification.

    SearchClause sc = new SearchClause(aq, jq, SearchClause.AND);
    asp.setSearchQualification(sc);
    
    
  6. Execute the Search and loop through the results to retrieve the LibraryObject that met the criteria. The LibraryObjects returned will be of the content type specified in the SearchClassSpecification.

    Search srch = new Search(session, asp);
    srch.open();
    
    int i;
    LibraryObject lo;
    SearchResultObject sro = srch.next();
    String lName;
    
    while (sro != null)
    {
        lo = sro.getLibraryObject();
        lName = lo.getName();
     
      try
      {
         sro = srch.next();
       }
       catch (IfsException e)
       {
         if (e.getErrorCode() == 22000)
         {
           break;
        }
        else
        {
            e.printStackTrace();
        }
      }
    }
    srch.close();
    

Fetching a PublicObject's Categories

The Oracle 9iFS Java API provides methods that make it easy to get the categories for PublicObjects, and the PublicObject associated with a Category instance.

The PublicObject class includes a method, getCategories(), which returns all Category instances that are associated with that PublicObject. Once you have the Category instance, you can retrieve the extra attributes applied to the PublicObject by the category.

Example 6-12 Fetching a PublicObject's Categories

  1. Assume that your application has already obtained the PublicObject

    PublicObject po = .....
    
    
  2. Fetch the PublicObject's Category instances

    Category[] cats = po.getCategories();
    
    
  3. For each category instance, determine the category type and fetch the category attributes.

    AttributeValue av; // variable to hold value of a category attribute
    Attribute[] catatts; // variable to hold the Attributes on the Category
    Category c; // variable to hold each Category instance
    ClassObject catco; // variable to hold the ClassObject
                       // that represents the category type
    int i, j, icount, jcount;
    String catName, attName; // variables to hold the names of 
                             //the category and attributes
    
    icount = (cats == null) ? 0 : cats.length;
    for(i=0; i < icount; i++)
    {
       c = cats[i];
       catco = c.getClassObject();
       catName = catco.getName();
       catatts = catco.getExtendedClassAttributes();
       jcount = (catatts == null) ? 0 : catatts.length;
       for (j=0; j < jcount; j++)
       {
           attName = catatts[j].getName();
           av = c.getAttribute(attName);
        }
     }
    
    

The Category class provides a convenience method, getAssociatedPublicObject(), that returns the PublicObject instance to which the category metadata applies. Once you have the PublicObject instance, you can retrieve all of the other attributes possessed by the PublicObject and call methods to manipulate the PublicObject.

Example 6-13 Fetching the Associated PublicObject from a Category instance

  1. Assume that your application has already obtained the Category instance

    Category cat = ......
    
    
  2. Fetch the PublicObject associated with the Category.

    PublicObject po = cat.getAssociatedPublicObject();
    
    
  3. Fetch the PublicObject's content type and attributes

    ClassObject co = po.getClassObject(); 
    Attribute[] atts = co.getEffectiveClassAttributes();
    String coName = co.getName();
    
    AttributeValue av; //variable to hold value of a PublicObject's attribute
    int i, icount;
    String attName;
    
    icount = (atts == null) ? 0 : atts.length;
    for (i = 0; i < icount; i++)
    {
       attName = atts[i].getName();
       av = po.getAttribute(attname);
    
    }
    

PropertyBundles

PropertyBundles are useful for persistently storing a "bag" of properties in Oracle 9iFS.

Compared to categories, PropertyBundles are relatively unstructured. The PropertyBundle consists of a set of Properties, each of which consists of a name/value pair. A PropertyBundle can exist independently in Oracle 9iFS, and be associated with zero, one, or more PublicObjects. PropertyBundles are a more flexible way to store data, but are not as easy to work with as more structured constructs such as categories.

Using PropertyBundles

PropertyBundles can be used to store ad-hoc metadata for processing systemwide tasks, one or more content types, or specific instances.

Since PropertyBundles can exist independently in Oracle 9iFS, and are used frequently for application processing, it may be useful to associate the PropertyBundle with a ValueDefault. By associating the PropertyBundle with a ValueDefault, it can be uniquely referenced by a string, the ValueDefault's UniqueName. PropertyBundles do not possess a UniqueName attribute, as do SchemaObjects such as ValueDefault. Although PropertyBundles possess a unique ID, the ID attribute does not provide a convenient way to reference PropertyBundles. ValueDefaults make it convenient to reference PropertyBundles. For example, in an XML configuration file, the UniqueName of the ValueDefault can be supplied as the value for an element referencing the PropertyBundle (e.g., <Update RefType = "ValueDefault">ContentTypeLookupByFileExtension</Update>). The Oracle 9iFS Java API also provides special methods for retrieving objects via a ValueDefault (e.g., LibrarySession.getValueDefaultCollection()).



NOTE:

To learn more about ValueDefaults, see Chapter 7, "Attribute Validation"


PropertyBundle Structure

A PropertyBundle consists of an array of name/value pairs. Each pair is represented by a Property object, which possesses a Name attribute and a Value attribute. The Value attribute can have any datatype supported by Oracle 9iFS (e.g., String, Integer, PublicObject, DirectoryObject_Array). The Property object possesses a third attribute, Bundle, which references the PropertyBundle to which it belongs.

Figure 6-1 PropertyBundle Object Model

Text description of pbobmod.gif follows.
Text description of the illustration pbobmod.gif

All objects in Oracle 9iFS possesses a PropertyBundle attribute. A PublicObject instance can use the inherited attribute to associate a PropertyBundle that is used to process a specific content type instance. A ClassObject instance can use the inherited attribute to associate a PropertyBundle that is used to process all instances of the content type that ClassObject represents.

Defining PropertyBundles

The Oracle 9iFS SDK supports two methods to define PropertyBundles:

Using XML to Create and Modify PropertyBundles

You can use XML files to define PropertyBundles in Oracle 9iFS. When the XML file is imported into Oracle 9iFS, the IfsSimpleXmlParser automatically uses it to create or modify a PropertyBundle instance. Oracle 9iFS does not support deleting PropertyBundles using XML.

It is recommended that a ValueDefault be created for each PropertyBundle so that the PropertyBundle can be referenced uniquely by a string. The following examples illustrate how to use XML to create PropertyBundle and ValueDefault in an XML file using the <OBJECTLIST> tag, and how to use a ValueDefault to update a PropertyBundle with an XML file.

Example 6-14 Using XML to Create PropertyBundles

<?xml version='1.0' standalone='yes'?>
<OBJECTLIST>

 <PROPERTYBUNDLE>
   <NAME>Title Translation PropertyBundle</NAME>
   <PROPERTIES>
     <PROPERTY>
       <NAME>English</NAME>
       <VALUE>Guide</VALUE>
     </PROPERTY>
     <PROPERTY>
       <NAME>Italian</NAME>
       <VALUE>Guida</VALUE>
     </PROPERTY>
   </PROPERTIES>
 </PROPERTYBUNDLE>

 <VALUEDEFAULT>
   <NAME>TranslatedTitleValueDefault</NAME>
   <VDVALUE Datatype="PublicObject" ClassName = "PropertyBundle" RefType = 
"Name">
     Title Translation PropertyBundle
   </VDVALUE>
 </VALUEDEFAULT>

</OBJECTLIST>

Example 6-15 Using XML to Modify PropertyBundles

<?xml version='1.0' standalone='yes'?>
 <PROPERTYBUNDLE>
  <UPDATE RefType='ValueDefault'>TranslatedTitleValueDefault</UPDATE>
   <PROPERTIES>
    <PROPERTY Action = 'add'>
     <NAME> Spanish </NAME>
      <VALUE DataType = 'String'>
          Guida
      </VALUE>
   </PROPERTY>
   <PROPERTY Action = 'Remove'>
      <NAME> Italian </NAME>
   </PROPERTY>
   <PROPERTY Action = 'Add'>
     <NAME> English </NAME>
      <VALUE DataType = 'String'>
          Manual
      </VALUE>
   </PROPERTY>
  </PROPERTIES>
 </PROPERTYBUNDLE>

Each element in the XML configuration file is used to specify the value for the attributes of the PropertyBundle and Property instances.



NOTE:

For a detailed description of the syntax rules for XML configuration files, consult Chapter 10, "XML and the Oracle Internet File System"


Table 6-1 lists each of the XML elements in a PropertyBundle configuration file. The table specifies the Java class and attribute in the Oracle 9iFS Java API that corresponds to the element, how the element is used, and any valid XML attributes for the element.


Table 6-1 PropertyBundle XML Configuration File Elements
Element  Class Information  Attributes  Usage 

<PROPERTYBUNDLE> 

PropertyBundle
extends ApplicationObject,
a subclass of PublicObject 

 

Root element of the PropertyBundle configuration file.
Must correspond to the name of the PropertyBundle class. 

<PROPERTIES> 

Does not directly correspond to an attribute of the PropertyBundle class. 

 

The declarations for the Properties of the PropertyBundle must be enclosed in a <PROPERTIES> element. 

<PROPERTY> 

Property
extends SystemObject 

Action 

Each policy is referenced by a <PROPERTY> element. 

<NAME> 

Name attribute on the Property class, inherited from the LibraryObject superclass. 

 

The <NAME> element is used to name each property in the bundle.  

<VALUE> 

The Value attribute on the Property class. 

Datatype
RefType 

The <VALUE> element is used to hold the value of the Property. The Datatype attribute on the <VALUE> element corresponds to the DataType attribute on the Property class.

The RefType attribute on the <VALUE> element can be used to reference a preexisting object (PublicObject, SystemObject, SchemaObject, DirectoryObject). 

Using Java to Create, Modify and Delete PropertyBundles

The Oracle 9iFS Java API provides a more robust interface for manipulating PropertyBundles. The Java API includes a set of classes, PropertyBundle and Property, that possess methods for manipulating ad-hoc data stored in PropertyBundles. The following examples illustrate how to create, modify and delete PropertyBundles with the Java API.

It is recommended that a ValueDefault be created for each PropertyBundle so that the PropertyBundle can be referenced uniquely by a string. The following examples also illustrate how to create a ValueDefault for a new PropertyBundle, and use the ValueDefault to access the PropertyBundle.

Example 6-16 Using Java to Create PropertyBundles

  1. Construct a PropertyBundleDefinition to temporarily hold the values.

    PropertyBundleDefinition pbdef = new PropertyBundleDefinition(session);
    pbdef.setAttribute(PropertyBundle.NAME_ATTRIBUTE,
       AttributeValue.newAttributeValue("Title Translation PropertyBundle"));
    
    
  2. Use the addPropertyValue() method on the PropertyBundleDefinition to define a new Property.

    pbdef.addPropertyValue("English", AttributeValue.newAttributeValue("Guide"));
    
    
  3. Construct a PropertyDefinition to add a new Property.

    PropertyDefinition pd = new PropertyDefinition(session);
    pd.setName("Italian");
    pd.setValue(AttributeValue.newAttributeValue("Guida"));
    pbdef.addPropertyDefinition(pd);
    
    
  4. Pass the PropertyBundleDefinition to the LibrarySession to create new PropertyBundle and Property instances.

    PropertyBundle pb = (PropertyBundle) session.createPublicObject(pbdef);
    
    
  5. Create a ValueDefaultPropertyBundle to hold the PropertyBundle in the ValueDefault.

    ValueDefaultPropertyBundleDefinition vdpbd = 
        new ValueDefaultPropertyBundleDefinition(session);
    vdpbd.setAttributeByUpperCaseName(ValueDefaultPropertyBundle.NAME_ATTRIBUTE,
                                 AttributeValue.newAttributeValue(
                                      "TranslatedTitleValueDefaultPropertyBundle"));
    vdpbd.setValue(pb);
    
    ValueDefaultPropertyBundle vdpb = (ValueDefaultPropertyBundle) 
    session.createPublicObject(vdpbd);
    
    
  6. Create a ValueDefault to allow the PropertyBundle to be referenced by a string. You must enable Administration Mode to create a ValueDefault since it extends SchemaObject.

    session.setAdministrationMode(true);
    
    ValueDefaultDefinition vdd = new ValueDefaultDefinition(session);
    vdd.setAttributeByUpperCaseName(ValueDefault.NAME_ATTRIBUTE,
                               AttributeValue.newAttributeValue(
                                    "TranslatedTitleValueDefault"));
    
    ValueDefault vd = (ValueDefault) session.createSchemaObject(vdd);
    vd.setValueDefaultPropertyBundle(vdpb);
    

Example 6-17 Using Java to Modify PropertyBundles

  1. Obtain the PropertyBundle to be modified.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = (ValueDefault) vdColl.getItems("TranslatedTitleValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PropertyBundle pb = (PropertyBundle) av.getPublicObject(session);
    
    
  2. Add a new Property for the PropertyBundle.

    pb.putPropertyValue("Spanish", AttributeValue.newAttributeValue("Guida"));
    
    
    
    
  3. Remove a new Property from the PropertyBundle.

    pb.removePropertyValue("Italian");
    
    
  4. Modify a Property in the PropertyBundle.

    pb.putPropertyValue("English",
                        AttributeValue.newAttributeValue("Manual"));
    

Example 6-18 Using Java to Delete PropertyBundles

  1. Obtain the PropertyBundle to be modified.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = (ValueDefault) vdColl.getItems("TranslatedTitleValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PropertyBundle pb = (PropertyBundle) av.getPublicObject(session);
    
    
  2. Delete the ValueDefault. Administration Mode must be enabled.

    session.setAdministrationMode(true);
    vd.free();
    
    
  3. Delete the PropertyBundle.

    pb.free();
    

Applying PropertyBundles to Content Types and Instances

PropertyBundles exist independently in Oracle 9iFS, and do not have to be associated with any other PublicObject to be used by an application. However, you may want to associate a PropertyBundle with one or more content types, or specific instances of a content type.

Every content type and instance in Oracle 9iFS possesses a PropertyBundle attribute that can reference the PropertyBundle that applies extra metadata to it. To associate a PropertyBundle with a content type, you would set the value of the PropertyBundle attribute on the ClassObject instance that represents that content type. To associate a PropertyBundle with a document, you would set the value of the PropertyBundle attribute on the Document instance to reference the PropertyBundle. To disassociate a PropertyBundle from a content type or instance, you would set the PropertyBundle attribute to NULL.

Oracle 9iFS allows you to use either XML configuration files or the Java API to apply PropertyBundles to content types and instances. The following sections illustrate how.

Using XML to Apply PropertyBundles

You can use XML configuration files to apply PropertyBundles to content types and instances at any time:

Example 6-19 Using XML to Apply a New PropertyBundle to a New Content Type

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <NAME>Image</NAME>   
    <SUPERCLASS RefType = "Name">Document</SUPERCLASS>  
    <PROPERTYBUNDLE>
      <NAME>Title Translation PropertyBundle</NAME>
      <PROPERTIES>
        <PROPERTY>
          <NAME>English</NAME>
          <VALUE>Guide</VALUE>
        </PROPERTY>
        <PROPERTY>
          <NAME>Italian</NAME>
          <VALUE>Guida</VALUE>
        </PROPERTY>
      </PROPERTIES>
    </PROPERTYBUNDLE>
    <ATTRIBUTES>
        <ATTRIBUTE>
            <NAME>Artists</NAME>
            <DATATYPE>Integer</DATATYPE>
        </ATTRIBUTE>
     </ATTRIBUTES>
</CLASSOBJECT>

Example 6-20 Using XML to Apply a Preexisting PropertyBundle to a New Content Type

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <NAME>Image</NAME>   
    <SUPERCLASS RefType = "Name">Document</SUPERCLASS>  
    <PROPERTYBUNDLE RefType = "ValueDefault">
      TranslatedTitleValueDefault
    </PROPERTYBUNDLE>
    <ATTRIBUTES>
        <ATTRIBUTE>
            <NAME>Artists</NAME>
            <DATATYPE>Integer</DATATYPE>
        </ATTRIBUTE>
     </ATTRIBUTES>
</CLASSOBJECT>

Example 6-21 Using XML to Apply a Preexisting PropertyBundle to a Preexisting Content Type

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <UPDATE RefType = "Name">IMAGE</UPDATE>
    <PROPERTYBUNDLE RefType = "ValueDefault">
        TranslatedTitleValueDefault
    </PROPERTYBUNDLE>
</CLASSOBJECT>

Example 6-22 Using XML to Apply a Preexisting PropertyBundle to a New Folder

<?xml version="1.0" standalone="yes"?>
<FOLDER>
    <NAME>Collateral</NAME>   
    <PROPERTYBUNDLE RefType = "ValueDefault">
      TranslatedTitleValueDefault
    </PROPERTYBUNDLE>
</FOLDER>

Example 6-23 Using XML to Apply an Existing PropertyBundle to an Existing Folder

<?xml version="1.0" standalone="yes"?>
<FOLDER>
    <UPDATE RefType = "Path">/home/guest/Collateral</UPDATE>   
    <PROPERTYBUNDLE RefType = "ValueDefault">
      TranslatedTitleValueDefault
    </PROPERTYBUNDLE>
</FOLDER>

Using Java to Apply PropertyBundles to Content Types and Instances

The Java API gives you greater control over how PropertyBundles are applied to content types and instances. For example, you might want to programmatically apply a PropertyBundle if the instance meets certain criteria. Or, you might want to create a PolicyPropertyBundle and PublicObject in a single transaction, to ensure that neither are created if either cannot.



NOTE:

For instructions on managing transactions in Oracle 9iFS, see Chapter 16, "Managing Sessions and Transactions"


Example 6-24 Using Java to Apply a New PropertyBundle to a New Content Type

  1. Create the PropertyBundle.

      PropertyBundleDefinition pbDef = new PropertyBundleDefinition(session);
      pbDef.setAttributeByUpperCaseName(PropertyBundle.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("Title Translation PropertyBundle"));
      pbDef.addPropertyValue("English", AttributeValue.newAttributeValue("Guide"));
      pbDef.addPropertyValue("Italian", AttributeValue.newAttributeValue("Guida"));
    
      PropertyBundle pb = (PropertyBundle) session.createPublicObject(pbDef);
    
    
  2. Create the ClassObjectDefinition. Administration Mode must be enabled.

      session.setAdministrationMode(true);
    
      ClassObjectDefinition coDef = new ClassObjectDefinition(session);
      coDef.setAttributeByUpperCaseName(ClassObject.NAME_ATTRIBUTE,
             AttributeValue.newAttributeValue("IMAGE"));
      ClassObject superClass = session.getClassObjectByName("DOCUMENT");
      coDef.setSuperclass(superClass);
    
    
  3. Set the PropertyBundle attribute on the ClassObjectDefinition to reference the new PropertyBundle.

      coDef.setAttributeByUpperCaseName(ClassObject.PROPERTYBUNDLE_ATTRIBUTE, 
              AttributeValue.newAttributeValue(pb));
    
      ClassObject classObj = (ClassObject) session.createSchemaObject(coDef);	
    

Example 6-25 Using Java to Apply a PropertyBundle to a Preexisting Content Type

  1. Fetch the PropertyBundle via its ValueDefault.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = (ValueDefault) vdColl.getItems("TranslatedTitleValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PropertyBundle pb = (PropertyBundle) av.getPublicObject(session);
    
    
  2. Fetch the ClassObject.

    ClassObject co = session.getClassObjectByName("IMAGE");
    
    
  3. Set the PropertyBundle attribute to reference the PropertyBundle. Administration Mode must be enabled.

    session.setAdministrationMode(true);
    
    co.setAttribute(ClassObject.PROPERTYBUNDLE_ATTRIBUTE,         
    AttributeValue.newAttributeValue(pb));
    

Example 6-26 Using Java to Apply a PropertyBundle to a New Folder

  1. Fetch the PropertyBundle via its ValueDefault.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = (ValueDefault) vdColl.getItems("TranslatedTitleValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PropertyBundle pb = (PropertyBundle) av.getPublicObject(session);
    
    FolderDefinition fd = new FolderDefinition(session);
    fd.setAttributeByUpperCaseName(Folder.NAME_ATTRIBUTE, 
         AttributeValue.newAttributeValue("Collateral"));
    fd.setAttributeByUpperCaseName(Folder.PROPERTYBUNDLE_ATTRIBUTE, 
         AttributeValue.newAttributeValue(pb));
    
    Folder f = (Folder) session.createPublicObject(fd);
    

Searching for Information based on PropertyBundles

You can use the Oracle 9iFS Java API to search for information based on PropertyBundle criteria. For example, you might search for all Properties that pertain to the file extension 'ppt'. You can build an application that queries for Properties based on their data by constructing a Selector with the Oracle 9iFS Java API.

Or, you might fetch all PublicObjects that have a Property named English whose value is Guide. You can use the Oracle 9iFS Java API to query for PublicObjects based on their PropertyBundles. To construct the query, the Search would include a PropertyQualification that joins the Property and PublicObject content types, and includes the additional criteria about the Property.



NOTE:

For detailed instructions on building Selectors and Searches, consult Chapter 8, "Building Search Applications".  


Example 6-27 Using a Selector to Fetch Properties

  1. Administration Mode must be enabled to select Properties.

    session.setAdministrationMode(true);
    
    
  2. Construct the Selector.

    Selector s = new Selector(session);
    s.setSearchClassname("PROPERTY");
    s.setSearchSelection("NAME = 'ppt'");
    
    
  3. Execute the query and retrieve each Property.

    LibraryObject[] props = s.getItems();
    
    Property p;
    int count = (props == null) ? 0 : props.length;
    for (i = 0; i < count; i++)
    {
       p = (Property) props[i];
    }
    

Example 6-28 Using a Search to Find all PublicObjects Based on Common Property Data

  1. Construct a SearchSpecification to hold the query criteria. This example does not include content criteria, so we construct an AttributeSearchSpecification.

    AttributeSearchSpecification asp = new AttributeSearchSpecification();
    
    
  2. Construct the SearchClassSpecification and set it on the AttributeSearchSpecification.

    String[] searchClasses = {"PUBLICOBJECT"};
    SearchClassSpecification scp = new SearchClassSpecification(searchClasses);
    scp.addResultClass("PUBLICOBJECT");
    
    asp.setSearchClassSpecification(scp);
    
    
  3. Construct a PropertyQualification to specify the Property criteria.

    PropertyQualification pq = new PropertyQualification();
    pq.setClassname("PUBLICOBJECT");
    pq.setPropertyName("English");
    pq.setOperatorType(AttributeQualification.EQUAL);
    pq.setValue(AttributeValue.newAttributeValue("Guide"));
    pq.setCaseIgnored(true);
    
    asp.setSearchQualification(pq);
    
    
  4. Execute the Search and loop through the results to retrieve the LibraryObject that met the criteria. The LibraryObjects returned will be of the content type specified in the SearchClassSpecification.

    Search srch = new Search(session, asp);
    srch.open();
    
    SearchResultObject sro = srch.next();
    LibraryObject lo;
    
    while (sro != null)
    {
       lo = sro.getLibraryObject();
       try
       {
          sro = srch.next();
       }
       catch ( IfsException e)
       {
         if (e.getErrorCode() == 22000)
         {
           break;
         }
         else
         {
           e.printStackTrace();
         }
       }
    }
    srch.close();
    

PolicyPropertyBundles

PolicyPropertyBundles provide a means to define policies, or business rules, for how certain operations are performed by an application. The logic for the business rule is implemented in a custom Java class. A policy is then defined to indicate that the business rule should be performed whenever a specific operation is called. A set of policies can be bundled together and associated with one or more content types or instances to hold all policies for how operations are performed on those objects. Subsequently, when an application tries to perform an operation, it can reference the PolicyPropertyBundle to determine if a policy has been defined for that operation. If a policy has been defined, the application can retrieve the Java class that implements the business rule and use it to perform the operation.

For example, Oracle 9iFS uses PolicyPropertyBundles to implement its Rendering framework. The Rendering framework provides an easy way for developers to plug-in renderers, which are automatically called by Oracle 9iFS to render instances of content types when fetched from different protocols. For example, the developer could configure Oracle 9iFS to render VCard instances in XML when fetched via FTP, and in VCard format when fetched via SMB. To configure the renderer, the developer creates a policy in the VCard content type's PolicyPropertyBundle. The Policy associates an operation named 'FtpContentRenderer' with the fully qualified name of the XML renderer that the developer wishes to use (e.g., 'MyApplication.Renderers.MyXMLRenderer'). Subsequently, when an instance of the content type is fetched, each protocol server is programmed to call a specific operation name. The Oracle 9iFS server references the PolicyPropertyBundle associated with the instance's content type to determine if a renderer has been associated with the operation specified. If it has, Oracle 9iFS retrieves the fully qualified name of the renderer, passes the instance to the renderer to be processed, and then passes the results to the protocol server.

Using PolicyPropertyBundles

PolicyPropertyBundles can be used to store policies used to perform systemwide tasks, operations on all instances of a content type, or operations on a specific instance.

Since PolicyPropertyBundles can exist independently in Oracle 9iFS, and are used frequently for application processing, it may be useful to associate the PolicyPropertyBundle with a ValueDefault. By associating the PolicyPropertyBundle with a ValueDefault, it can be uniquely referenced by a string, the ValueDefault's UniqueName. For example, in an XML configuration file, the UniqueName of the ValueDefault can be supplied as the value for an element referencing the PolicyPropertyBundle (e.g., <Update RefType = "ValueDefault">MyPolicyPropertyBundleValueDefault</Update>). The Oracle 9iFS Java API also provides a special methods for retrieving objects via a ValueDefault (e.g., LibrarySession.getValueDefaultCollection()).



NOTE:

Oracle 9iFS Manager does not currently provide an interface for defining PropertyBundles. However, it does allow you to search and view PropertyBundle information. For instructions on how to use the search interface in Oracle 9iFS Manager, consult the Oracle 9iFS Setup and Administration Guide


PolicyPropertyBundle Structure

Each policy for an operation is defined in Oracle 9iFS as an instance of the Policy content type. Policy possesses attributes for storing the operation to which the policy applies, the fully qualified name of the Java bean that implements the behavior of the policy, and an enumerated key to identify the policy.

Table 6-2 Policy Attributes
Attribute  Usage 

Name 

The name of this Policy. Every persistent object in Oracle 9iFS is named. 

Operation 

The name of the Oracle 9iFS server operation that this Policy carries out. 

ImplementationName 

The fully qualified name of the Java class. 

ImplementationNum 

An enumerated key to identify the Policy. (This attribute is not used when plugging in renderers) 

Policies are bundled together by a PolicyPropertyBundle instance. The PolicyPropertyBundle content type extends the PropertyBundle content type. Therefore, it has the same structure as a PropertyBundle. However, in this case, the value of a Property in the PropertyBundle references a Policy.

Figure 6-2 PolicyPropertyBundle Object Model


Text description of ppbobmod.gif follows.
Text description of the illustration ppbobmod.gif


NOTE:

For a description of the structure of PropertyBundles, see "PropertyBundles"


The top-level content type in Oracle 9iFS, LibraryObject, possesses a PolicyBundle attribute. This attribute is inherited by all Oracle 9iFS content types. A ClassObject instance can use the inherited attribute to associate a PolicyPropertyBundle that is used to process all instances of the content type that the ClassObject represents. A PublicObject instance can use the inherited attribute to associate a PolicyPropertyBundle that is used to define policies for operations on that specific instance.

Defining PolicyPropertyBundles

To implement policies for how operations are performed by a custom application, you need to define the following:

  1. Operation names. Define the operations that your application uses to reference a specific task being performed.

  2. Policy Implementation Classes. Create Java classes that implement the behavior of the policy for the operation.

  3. PolicyPropertyBundle. Create a PolicyPropertyBundle that associates your custom operations with the Java class that implements the policy.

  4. Custom Application Logic. You would then build special logic into your custom application that employs the PolicyPropertyBundle to apply ad-hoc behavior when performing tasks. Your application clients could specify an operation to be performed. On receiving the operation, your application server could reference the Java class and use it to perform the operation.

This section provides instructions on defining PolicyPropertyBundles that associate Java classes with custom operations. It does not discuss how to build the Java classes that implement the policy behavior or custom application logic since these are unique to your application. Oracle 9iFS places no special requirements on creating these Java classes.

Oracle 9iFS SDK supports several methods to define PolicyPropertyBundles:

Using XML to Create and Modify PolicyPropertyBundles

You can use XML files to define PolicyPropertyBundles in Oracle 9iFS. When the XML file is imported into Oracle 9iFS, the IfsSimpleXmlParser automatically uses it to create or modify a PolicyPropertyBundle instance. Oracle 9iFS does not support deleting PolicyPropertyBundles using XML.

It is recommended that a ValueDefault be created for each PolicyPropertyBundle so that the PolicyPropertyBundle can be referenced uniquely by a string. The following examples illustrate how to use XML to create PolicyPropertyBundle and ValueDefault in an XML file using the <OBJECTLIST> tag, and how to use a ValueDefault to update a PolicyPropertyBundle with an XML file.

Example 6-29 Using XML to Create PolicyPropertyBundles

<?xml version='1.0' standalone='yes'?>
<OBJECTLIST>
 <POLICYPROPERTYBUNDLE>
   <NAME>Delivery Policies PolicyPropertyBundle</NAME>
   <POLICIES>
     <PROPERTY>
       <NAME>Fax</NAME>
       <VALUE Datatype="SystemObject" ClassName="Policy">
           <NAME>FaxPolicy</NAME>
           <OPERATION>SendByFax</OPERATION>
           <IMPLEMENTATIONNAME>
              MyCompany.MyApp.DeliveryServers.FaxServer
           </IMPLEMENTATIONNAME>
           <IMPLEMENTATIONENUM>1</IMPLEMENTATIONENUM>
       </VALUE>
     </PROPERTY>
     <PROPERTY>
       <NAME>Print</NAME>
       <VALUE Datatype="SystemObject" ClassName="Policy">
           <NAME>PrintPolicy</NAME>
           <OPERATION>SendByPrinter</OPERATION>
           <IMPLEMENTATIONNAME>
              MyCompany.MyApp.DeliveryServers.PrintServer
           </IMPLEMENTATIONNAME>
           <IMPLEMENTATIONENUM>2</IMPLEMENTATIONENUM>
       </VALUE>
     </PROPERTY>
   </POLICIES>
 </POLICYPROPERTYBUNDLE>

 <VALUEDEFAULT>
   <NAME>DeliveryPoliciesValueDefault</NAME>
   <VDVALUE Datatype="PublicObject" ClassName = "PolicyPropertyBundle" 
     RefType = "Name">
        Delivery Policies PolicyPropertyBundle
   </VDVALUE>
 </VALUEDEFAULT>
</OBJECTLIST>

Example 6-30 Using XML to Add Policies to PolicyPropertyBundles

<?xml version='1.0' standalone='yes'?>
 <POLICYPROPERTYBUNDLE>
  <UPDATE RefType='ValueDefault'>DeliveryPoliciesValueDefault</UPDATE>
   <POLICIES>
    <PROPERTY Action = 'add'>
     <NAME>Mail</NAME>
      <VALUE Datatype = 'SystemObject' ClassName="Policy">
           <NAME>MailPolicy</NAME>
           <OPERATION>SendByMail</OPERATION>
           <IMPLEMENTATIONNAME>
              MyCompany.MyApp.DeliveryServers.MailServer
           </IMPLEMENTATIONNAME>
           <IMPLEMENTATIONENUM>2</IMPLEMENTATIONENUM>
       </VALUE>
   </PROPERTY>
  </POLICIES>
 </POLICYPROPERTYBUNDLE>

Example 6-31 Using XML to Remove Policies from PolicyPropertyBundles

<?xml version='1.0' standalone='yes'?>
 <POLICYPROPERTYBUNDLE>
   <UPDATE RefType='ValueDefault'>DeliveryPoliciesValueDefault</UPDATE>
   <POLICIES>
    <PROPERTY Action = 'remove'>
      <NAME>Fax</NAME>
    </PROPERTY>
  </POLICIES>
 </POLICYPROPERTYBUNDLE>

Example 6-32 Using XML to Modify Policies

<?xml version='1.0' standalone='yes'?>
 <POLICY>
    <UPDATE RefType = "Name">MailPolicy</UPDATE>
    <IMPLEMENTATIONENUM>1</IMPLEMENTATIONENUM>
 </POLICY>

Each element in the XML configuration file is used to specify the value for the attributes of the PolicyPropertyBundle and Policy instances.

Table 6-3 lists each of the XML elements in a PolicyPropertyBundle configuration file. The table specifies the Java class and attribute in the Oracle 9iFS Java API that corresponds to the element, how the element is used, and any valid XML attributes for the element.

Table 6-3 PolicyPropertyBundle XML Configuration File Elements
Element  Class Information  Attributes  Usage 

<POLICYPROPERTYBUNDLE> 

PolicyPropertyBundle
extends ApplicationObject,

a subclass of PublicObject 

 

Root element of the PolicyPropertyBundle configuration file.
Must correspond to the name of the PolicyPropertyBundle class. 

<POLICIES> 

Does not directly correspond to an attribute of the PolicyPropertyBundle class. 

 

The declarations for the Properties of the PolicyPropertyBundle must be enclosed in a <POLICIES> element. 

<PROPERTY> 

Property,
extends SystemObject 

Action 

Each policy is referenced by a <PROPERTY> element. 

<NAME> 

Name attribute on the Property class, inherited from the LibraryObject superclass. 

 

The <NAME> element is used to name each property in the bundle.  

<VALUE> 

The Value attribute on the Property class. 

Datatype
RefType 

The <VALUE> element is used to hold the Policy that the Property references.

The Datatype attribute on the <VALUE> element corresponds to the DataType attribute on the Property class. In the case of a PolicyPropertyBundle, the Datatype is always SystemObject, because the Value references a Policy that extends SystemObject.

The RefType attribute on the <VALUE> element can be used to reference a preexisting Policy. 

<POLICY> 

Policy,
extends SystemObject 

 

The <POLICY> element holds the declaration of a Policy. 

<NAME> 

The Name attribute on the Policy class, inherited from the LibraryObject superclass. 

 

The name of the Policy. 

<OPERATION> 

Operation attribute on the Policy class. 

 

The <OPERATION> element is used to specify the operation for which the policy is being defined. 

<IMPLEMENTATIONNAME> 

ImplementationName attribute on the Policy class. 

 

The fully qualified name of the Java class that implements the behavior of the policy. 

<IMPLEMENTATIONNUM> 

ImplementationNum attribute on the Policy class. 

 

An integer that enumerates the Policy. 

Using Java to Create, Modify, and Delete PolicyPropertyBundles

You can also use the Oracle 9iFS Java API to define PolicyPropertyBundles. The Java APIs provide methods for manipulating the operation and policy implementation class defined in each policy.

Example 6-33 Using Java to Create PolicyPropertyBundles

  1. Administration Mode must be enabled to create Policies.

    session.setAdministrationMode(true);
    
    
  2. Construct each Policy in the PolicyPropertyBundle.

    PolicyDefinition poldef = new PolicyDefinition(session);
    poldef.setAttributeByUpperCaseName(Policy.NAME_ATTRIBUTE,
         AttributeValue.newAttributeValue("FaxPolicy"));
    poldef.setAttributeByUpperCaseName(Policy.OPERATION_ATTRIBUTE,
         AttributeValue.newAttributeValue("SendByFax"));
    poldef.setAttributeByUpperCaseName(Policy.IMPLEMENTATIONNAME_ATTRIBUTE,
         AttributeValue.newAttributeValue(
            "MyCompany.MyApp.DeliveryServers.FaxServer"));
    Policy pol1 = (Policy) session.createSystemObject(poldef);
    
    poldef.setAttributeByUpperCaseName(Policy.NAME_ATTRIBUTE,
         AttributeValue.newAttributeValue("PrintPolicy"));
    poldef.setAttributeByUpperCaseName(Policy.OPERATION_ATTRIBUTE,
         AttributeValue.newAttributeValue("SendByPrinter"));
    poldef.setAttributeByUpperCaseName(Policy.IMPLEMENTATIONNAME_ATTRIBUTE,
         AttributeValue.newAttributeValue(
            "MyCompany.MyApp.DeliveryServers.PrintServer"));
    Policy pol2 = (Policy) session.createSystemObject(poldef);
    
    
  3. Construct a PolicyPropertyBundleDefinition to temporarily hold the values.

    PolicyPropertyBundleDefinition ppbdef = 
        new PolicyPropertyBundleDefinition(session);
    ppbdef.setAttributeByUpperCaseName(PolicyPropertyBundle.NAME_ATTRIBUTE,
        AttributeValue.newAttributeValue("Delivery Policies PolicyPropertyBundle"));
    ppbdef.addPropertyValue("Fax", AttributeValue.newAttributeValue(pol1));
    ppbdef.addPropertyValue("Print", AttributeValue.newAttributeValue(pol2));
    
    
  4. Pass the PolicyPropertyBundleDefinition to the LibrarySession to create new PolicyPropertyBundle and Policy instances.

    PolicyPropertyBundle ppb = 
        (PolicyPropertyBundle) session.createPublicObject(ppbdef);
             
    
  5. Create a ValueDefaultPropertyBundle to hold the PolicyPropertyBundle in the ValueDefault.

    ValueDefaultPropertyBundleDefinition vdpbd = 
        new ValueDefaultPropertyBundleDefinition(session);
    vdpbd.setAttributeByUpperCaseName(ValueDefaultPropertyBundle.NAME_ATTRIBUTE,
        AttributeValue.newAttributeValue(
            "DeliveryPoliciesValueDefaultPropertyBundle"));
    vdpbd.setValue(ppb);
    
    ValueDefaultPropertyBundle vdpb = 
        (ValueDefaultPropertyBundle) session.createPublicObject(vdpbd);
    
    
  6. Create a ValueDefault to allow the PolicyPropertyBundle to be referenced by a string.

    ValueDefaultDefinition vdd = new ValueDefaultDefinition(session);
    vdd.setAttributeByUpperCaseName(ValueDefault.NAME_ATTRIBUTE,
        AttributeValue.newAttributeValue(
           "DeliveryPoliciesValueDefault"));
    
    ValueDefault vd = (ValueDefault) session.createSchemaObject(vdd);
    vd.setValueDefaultPropertyBundle(vdpb);
    
    

Example 6-34 Using Java to Modify PolicyPropertyBundles

  1. Obtain the PolicyPropertyBundle to be modified.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = (ValueDefault)vdColl.getItems("DeliveryPoliciesValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PolicyPropertyBundle ppb = (PolicyPropertyBundle) av.getPublicObject(session);
    
    
  2. Add a new Policy to the PolicyPropertyBundle.

    PolicyDefinition poldef = new PolicyDefinition(session);
    poldef.setAttributeByUpperCaseName(Policy.NAME_ATTRIBUTE,
         AttributeValue.newAttributeValue("MailPolicy"));
    poldef.setAttributeByUpperCaseName(Policy.OPERATION_ATTRIBUTE,
         AttributeValue.newAttributeValue("SendByMail"));
    poldef.setAttributeByUpperCaseName(Policy.IMPLEMENTATIONNAME_ATTRIBUTE,
         AttributeValue.newAttributeValue(
            "MyCompany.MyApp.DeliveryServers.MailServer"));
    Policy pol = session.createSystemObject(poldef);
    
    ppb.putPropertyValue("Spanish", AttributeValue.newAttributeValue(pol));
    
    
  3. Remove a new Property from the PropertyBundle.

    ppb.removePropertyValue("Fax");
    
    
  4. Modify a Policy in the PropertyBundle.

    AttributeValue av = ppb.getPropertyValue("Mail");
    Policy pol = (Policy) av.getSystemObject(session);
    pol.setImplementationEnum(1);
    

Example 6-35 Using Java to Delete PolicyPropertyBundles

  1. Obtain the PolicyPropertyBundle to be deleted from the ValueDefault.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = 
          (ValueDefault) vdColl.getItems("DeliveryPoliciesValueDefault");
    ValueDefaultPropertyBundle vdpb = vd.getValueDefaultPropertyBundle();
    AttributeValue av = vd.getPropertyValue();
    PolicyPropertyBundle ppb = (PolicyPropertyBundle) av.getPublicObject(session);
    
    
  2. Get the PolicyPropertyBundle's Policies.

    Property[] props = ppb.getProperties();
    int count = (props == null) ? 0 : props.length;
    
    
  3. Delete the Policies first. Administration Mode must be enabled to delete Policies.

    session.setAdministrationMode(true);
    int i;
    Policy p;
    for (i = 0; i < count; i++)
    {
      p = (Policy) props[i].getValue().getSystemObject(session);
      p.free();
    }
    
  4. Delete the PolicyPropertyBundle.

    ppb.free();
    
    
  5. Delete the ValueDefault and ValueDefaultPropertyBundle.

    vd.free();
    vdpb.free();
    

Applying PolicyPropertyBundles to Content Types and Instances

PolicyPropertyBundles exist independently in Oracle 9iFS, and do not have to be associated with any other PublicObject to be used by an application. However, you can associate a PolicyPropertyBundle with one or more content types, or specific instances of a content type, to define custom policies for operations performed specifically on these objects.

Every content type and instance in Oracle 9iFS possesses a PolicyBundle attribute, which can reference the PolicyPropertyBundle. To associate a PolicyPropertyBundle with a content type, you would set the value of the PolicyBundle attribute on the ClassObject instance that represents that content type. To associate a PolicyPropertyBundle with a document, you set the value of the PolicyBundle attribute on the Document instance to reference the PolicyPropertyBundle. To disassociate a PolicyPropertyBundle from a content type or instance, you set the PolicyBundle attribute to NULL.

Oracle 9iFS allows you to use either XML configuration files or the Java API to apply PolicyPropertyBundles to content types and instances.

Using XML to Apply PolicyPropertyBundles

You can use XML configuration files to apply PolicyPropertyBundles to content types and instances at any time:

Example 6-36 Using XML to Apply a New PolicyPropertyBundle to a New Content Type

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <NAME>Image</NAME>   
    <SUPERCLASS RefType = "Name">Document</SUPERCLASS>  
    <POLICYBUNDLE>
     <NAME>Delivery Policies PolicyPropertyBundle</NAME>
     <POLICIES>
      <PROPERTY>
       <NAME>Fax</NAME>
       <VALUE Datatype="SystemObject" ClassName="Policy">
           <NAME>FaxPolicy</NAME>
           <OPERATION>SendByFax</OPERATION>
           <IMPLEMENTATIONNAME>
              MyCompany.MyApp.DeliveryServers.FaxServer
           </IMPLEMENTATIONNAME>
           <IMPLEMENTATIONENUM>1</IMPLEMENTATIONENUM>
       </VALUE>
      </PROPERTY>
      <PROPERTY>
       <NAME>Print</NAME>
       <VALUE Datatype="SystemObject" ClassName="Policy">
           <NAME>PrintPolicy</NAME>
           <OPERATION>SendByPrinter</OPERATION>
           <IMPLEMENTATIONNAME>
              MyCompany.MyApp.DeliveryServers.PrintServer
           </IMPLEMENTATIONNAME>
           <IMPLEMENTATIONENUM>2</IMPLEMENTATIONENUM>
       </VALUE>
      </PROPERTY>
     </POLICIES>
    </POLICYBUNDLE>
    <ATTRIBUTES>
        <ATTRIBUTE>
            <NAME>Artists</NAME>
            <DATATYPE>DirectoryObject_Array</DATATYPE>
        </ATTRIBUTE>
     </ATTRIBUTES>
</CLASSOBJECT>

Example 6-37 Using XML to Apply a Preexisting PropertyBundle to a New Content Type

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <NAME>Image</NAME>   
    <SUPERCLASS RefType = "Name">Document</SUPERCLASS>  
    <POLICYBUNDLE RefType = "ValueDefault">
         DeliveryPoliciesValueDefault
    </POLICYBUNDLE>
    <ATTRIBUTES>
        <ATTRIBUTE>
            <NAME>Artists</NAME>
            <DATATYPE>DirectoryObject_Array</DATATYPE>
        </ATTRIBUTE>
     </ATTRIBUTES>
</CLASSOBJECT>

Example 6-38 Using XML to Apply a Preexisting PropertyBundle to a Preexisting Content Type

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <UPDATE RefType = "Name">IMAGE</UPDATE>
    <POLICYBUNDLE RefType = "ValueDefault">
      DeliveryPoliciesValueDefault
    </POLICYBUNDLE>
</CLASSOBJECT>

Using Java to Apply PolicyPropertyBundles to Content Types and Instances

The Java API gives you greater control over how PolicyPropertyBundles are applied to content types and instances. For example, you might want to programmatically apply a PolicyPropertyBundle if the instance meets certain criteria. Or, you might want to create a PolicyPropertyBundle and PublicObject in a single transaction, to ensure that neither are created if either cannot.



NOTE:

For instructions on managing transactions in Oracle 9iFS, see Chapter 16, "Managing Sessions and Transactions".  


Example 6-39 Using Java to Apply a New PolicyPropertyBundle to a New Content Type

  1. Construct each Policy in the PolicyPropertyBundle.

    PolicyDefinition poldef = new PolicyDefinition(session);
    poldef.setAttributeByUpperCaseName(Policy.NAME_ATTRIBUTE,
           AttributeValue.newAttributeValue("FaxPolicy"));
    poldef.setAttributeByUpperCaseName(Policy.OPERATION_ATTRIBUTE,
           AttributeValue.newAttributeValue("SendByFax"));
    poldef.setAttributeByUpperCaseName(Policy.IMPLEMENTATIONNAME_ATTRIBUTE,
           AttributeValue.newAttributeValue(
             "MyCompany.MyApp.DeliveryServers.FaxServer"));
    Policy pol1 = (Policy) session.createSystemObject(poldef);
    
    poldef.setAttributeByUpperCaseName(Policy.NAME_ATTRIBUTE,
           AttributeValue.newAttributeValue("PrintPolicy"));
    poldef.setAttributeByUpperCaseName(Policy.OPERATION_ATTRIBUTE,
           AttributeValue.newAttributeValue("SendByPrinter"));
    poldef.setAttributeByUpperCaseName(Policy.IMPLEMENTATIONNAME_ATTRIBUTE,
           AttributeValue.newAttributeValue(
             "MyCompany.MyApp.DeliveryServers.PrintServer"));
    Policy pol2 = (Policy) session.createSystemObject(poldef);
    
    
  2. Create the PolicyPropertyBundle.

    PolicyPropertyBundleDefinition ppbdef = 
           new PolicyPropertyBundleDefinition(session);
    ppbdef.setAttributeByUpperCaseName(PolicyPropertyBundle.NAME_ATTRIBUTE,
           AttributeValue.newAttributeValue(
             "Delivery Policies PolicyPropertyBundle"));
    ppbdef.addPropertyValue("Fax", AttributeValue.newAttributeValue(pol1));
    ppbdef.addPropertyValue("Print", AttributeValue.newAttributeValue(pol2));
    
    
  3. Pass the PolicyPropertyBundleDefinition to the LibrarySession to create new PolicyPropertyBundle and Policy instances.

    PolicyPropertyBundle ppb = 
          (PolicyPropertyBundle) session.createPublicObject(ppbdef);
    
    
  4. Create the ClassObjectDefinition.

    ClassObjectDefinition codef = new ClassObjectDefinition(session);
    codef.setAttributeByUpperCaseName(ClassObject.NAME_ATTRIBUTE,
          AttributeValue.newAttributeValue("IMAGE"));
    ClassObject superClass = session.getClassObjectByName("DOCUMENT");
    codef.setSuperclass(superClass);
    
    
  5. Set the PropertyBundle attribute on the ClassObjectDefinition to reference the new PropertyBundle.

    codef.setAttributeByUpperCaseName(ClassObject.POLICYBUNDLE_ATTRIBUTE, 
          AttributeValue.newAttributeValue(ppb));
    ClassObject classObj = (ClassObject) session.createSchemaObject(codef);
    

Example 6-40 Using Java to Apply a PolicyPropertyBundle to a Preexisting Content Type

  1. Fetch the PolicyPropertyBundle via its ValueDefault.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = 
           (ValueDefault) vdColl.getItems("DeliveryPoliciesValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PolicyPropertyBundle ppb = (PolicyPropertyBundle) av.getPublicObject(session);
    
    
  2. Fetch the ClassObject.

    ClassObject co = session.getClassObjectByName("IMAGE");
    
    
  3. Set the PropertyBundle attribute to reference the PropertyBundle. Administration Mode must be enabled.

    session.setAdministrationMode(true);
    co.setAttribute(ClassObject.POLICYBUNDLE_ATTRIBUTE,
        AttributeValue.newAttributeValue(ppb));
    

Example 6-41 Using Java to Apply a PolicyPropertyBundle to a New Folder

  1. Fetch the PropertyBundle via its ValueDefault.

    Collection vdColl = session.getValueDefaultCollection();
    ValueDefault vd = 
         (ValueDefault) vdColl.getItems("DeliveryPoliciesValueDefault");
    AttributeValue av = vd.getPropertyValue();
    PolicyPropertyBundle ppb = (PolicyPropertyBundle) av.getPublicObject(session);
    
    FolderDefinition fd = new FolderDefinition(session);
    fd.setAttributeByUpperCaseName(Folder.NAME_ATTRIBUTE, 
         AttributeValue.newAttributeValue("Collateral"));
    fd.setAttributeByUpperCaseName(Folder.POLICYBUNDLE_ATTRIBUTE, 
         AttributeValue.newAttributeValue(ppb));
    
    Folder f = (Folder) session.createPublicObject(fd);
    

Relationships

Oracle 9iFS not only allows you to manage documents, folders, and other types of information, it allows you to manage the associations between them. Oracle 9iFS provides three methods for associating objects:

You can use Relationships to model complex types of information, such as compound documents. Compound documents are comprised of multiple components, which can be reused in multiple compound documents. Different types of compound documents can use different methods for managing the relationships between the components, including OLE, Hurls, and proprietary definition files (i.e., FrameMaker .bk files). You can define custom types of relationships that possess the attributes and methods required to manage different types of compound documents.

Defining New Types of Relationships

Defining new types of relationships entails the same steps required for defining any custom content type. As for any other content type, you create a set of SchemaObject instances to represent the relationship type. You can also define custom behavior for the relationship type by implementing Java classes. However, implementing custom Java classes is not required to define a new relationship type. Afterward, you can modify and delete the relationship type by editing or deleting its SchemaObjects. These development tasks can be done with the Java API, XML files, or Oracle 9iFS Manager.



NOTE:

For detailed instructions on creating, modifying, and deleting custom content types, see Chapter 5, "Extending Content Types and Attributes" and Chapter 17, "Customizing Content Type Behavior". If you have already read these chapters, this section provides quick review how to create, modify, and delete relationship types with Java and XML. 


Creating Relationship Types

To create a new type of relationship, you create a new content type that extends Relationship and adds attributes and methods that are required for managing that type of association. For example, you could create a new relationship, BookRelationship, that extends Relationship and includes the extended attribute ComponentLabel.

To define the new relationship type, follow these steps:

Example 6-42 Using XML to Create Relationship Types

<?xml version="1.0" standalone="yes"?>
<CLASSOBJECT>
    <NAME>BookRelationship</NAME>   
    <SUPERCLASS RefType = "Name">Relationship</SUPERCLASS>  
    <DESCRIPTION>Relationships between a Book and its components.</DESCRIPTION>
    <ATTRIBUTES>
        <ATTRIBUTE>
            <NAME>ComponentLabel</NAME>
            <DATATYPE>String</DATATYPE>
        </ATTRIBUTE>
    </ATTRIBUTES>
</CLASSOBJECT>


NOTE:

For a description of each element in an XML file used to create relationship types, see Chapter 5, "Extending Content Types and Attributes" 


Example 6-43 Using Java to Create Relationship Types

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
  2. Create a ClassObjectDefinition to hold the values for the ClassObject that represents the relationship type.

    ClassObjectDefinition codef = new ClassObjectDefinition(session);
    codef.setAttributeByUpperCaseName(ClassObject.NAME_ATTRIBUTE,
         AttributeValue.newAttributeValue("BookRelationship"));
    
    
  3. Specify that your new relationship type extends the Relationship content type.

    ClassObject catco = session.getClassObjectByName("RELATIONSHIP");
    codef.setSuperclass(catco);
    
    
  4. Create AttributeDefinitions for each attribute pertaining to the relationship type. Add the AttributeDefinitions to the ClassObjectDefinition.

    AttributeDefinition attdef1 = new AttributeDefinition(session);
    attdef1.setAttributeByUpperCaseName(Attribute.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("ComponentLabel"));
    attdef1.setAttributeByUpperCaseName(Attribute.DATATYPE_ATTRIBUTE,
            AttributeValue.newAttributeValue(Attribute.ATTRIBUTEDATATYPE_STRING));
    codef.addAttributeDefinition(attdef1);
    
    AttributeDefinition attdef2 = new AttributeDefinition(session);
    attdef2.setAttributeByUpperCaseName(Attribute.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("FullPath"));
    attdef2.setAttributeByUpperCaseName(Attribute.DATATYPE_ATTRIBUTE,
            AttributeValue.newAttributeValue(Attribute.ATTRIBUTEDATATYPE_STRING));
    codef.addAttributeDefinition(attdef2);
    
    
    
  5. Create the ClassObject and Attributes for the new relationship type.

    ClassObject co = (ClassObject) session.createSchemaObject(codef);
    

Modifying Relationship Types

You can add and remove attributes on a relationship type after it has been created.



NOTE:

You cannot use XML to add or remove attributes from a relationship type. You must do this with Oracle 9iFS Manager or the Java API.

For instructions on deleting attributes with Oracle 9iFS Manager, see the Oracle 9iFS Setup and Administration Guide


Example 6-44 Using Java to Add, Remove, and Update Attributes on Relationship Types

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
  2. Get the ClassObject that represents the relationship type.

    ClassObject relco = session.getClassObjectByName("BOOKRELATIONSHIP");
    
    
  3. Adding an Attribute to the ClassObject.

    AttributeDefinition attdef1 = new AttributeDefinition(session);
    attdef1.setAttributeByUpperCaseName(Attribute.NAME_ATTRIBUTE,
            AttributeValue.newAttributeValue("RelativePath"));
    attdef1.setAttributeByUpperCaseName(Attribute.DATATYPE_ATTRIBUTE,
            AttributeValue.newAttributeValue(Attribute.ATTRIBUTEDATATYPE_STRING));
    relco.addAttribute(attdef1);
    
    
  4. Removing an Attribute from the ClassObject.

    Attribute att2 = catco.getEffectiveClassAttributes("FULLPATH");
    relco.removeAttribute(att2);
    
    
  5. Updating an Attribute on the ClassObject.

    Attribute att3 = catco.getEffectiveClassAttributes("COMPONENTLABEL");
    Collection vdColl = session.getValueDomainCollection();
    ValueDomain vd = vdColl.getItems("ComponentLabelValueDomain");
    att3.setValueDomain(vd);
    

Deleting Relationship Types

You can use the Java API or Oracle 9iFS Manager to delete relationship types. If instances exist for the relationship type, they must be removed before it can be removed.



NOTE:

For instructions on deleting the ClassObject for a relationship type with Oracle 9iFS Manager, see the Oracle 9iFS Setup and Administration Guide


Example 6-45 Using Java to Delete Relationship Types

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
  2. Get the ClassObject that represents the relationship type.

    ClassObject relco = session.getClassObjectByName("BOOKRELATIONSHIP");
    
    
  3. Delete the ClassObject by calling the free() method.

relco.free();

Relating Objects

Once you have created a new relationship type, you can use it to relate two PublicObjects. This section describes the following tasks:

Creating Relationships between PublicObjects

To relate two PublicObjects, you create a new instance of your relationship type.

Using Java to Relate PublicObjects

To relate two PublicObjects with the Java API, follow these steps:

  1. Create a RelationshipDefinition to hold the values for the new Relationship instance.

  2. Specify the type of the new relationship.

  3. Specify the PublicObjects that constitute the Left_Object and Right_Object in the relationship.

  4. Set the values of any extended relationship attributes.

Example 6-46 Using Java to Relate PublicObjects

  1. Assume that you have already obtained the PublicObjects to be related.

    PublicObject po1 = .....
    PublicObject po2 = .....
    
    
  2. Create a new RelationshipDefinition.

    RelationshipDefinition rdef = new RelationshipDefinition(session);
    
    
  3. Specify the type of the new Relationship instance.

    ClassObject co = session.getClassObjectByName("BOOKRELATIONSHIP");
    rdef.setClassObject(co);
    
    
  4. Specify the PublicObject on the left-hand side and right-hand side of the relationship.

    rdef.setAttributeByUpperCaseName(Relationship.LEFTOBJECT_ATTRIBUTE,
        AttributeValue.newAttributeValue(po1));
    rdef.setAttributeByUpperCaseName(Relationship.RIGHTOBJECT_ATTRIBUTE,
        AttributeValue.newAttributeValue(po2));
    
    
  5. Set the values of any extended relationship attributes.

    rdef.setAttributeByUpperCaseName("COMPONENTLABEL",
             AttributeValue.newAttributeValue("Chapter 1"));
    
    
  6. Use the RelationshipDefinition to create a new relationship between the PublicObjects.

    Relationship r = (Relationship) session.createSystemObject(rdef);
    
Using XML to Relate PublicObjects

Administrators can also use XML to relate PublicObjects. When the XML file is imported into Oracle 9iFS, the IfsSimpleXmlParser automatically parses the file and generate an instance of the relationship type. The following are the key aspects of an XML file used to relate PublicObjects:

Example 6-47 Using XML to Relate PublicObjects

<?xml version="1.0" standalone="yes"?>
<BOOKRELATIONSHIP>
    <LEFTOBJECT RefType = "Path">/home/guest/Manuals/UserGuide.bk</LEFTOBJECT>
    <RIGHTOBJECT RefType = "Path">
        /home/guest/Manuals/UserAdmin.fm
    </RIGHTOBJECT>
    <COMPONENTLABEL>Chapter 1 : User Administration</COMPONENTLABEL>
</BOOKRELATIONSHIP>

If you use an XML file to create new PublicObjects, you can relate the PublicObject in the same XML file. To do so, the element containing the new PublicObject's data must be specified first in the XML file. Then, an element containing the relationship data can follow, referencing the PublicObject instances created by the preceding elements. Oracle 9iFS creates the instances for each element sequentially, first the PublicObjects, then the relationship instance. For this reason, the element representing the relationship instance can reference the PublicObjects as if they already exist.

Example 6-48 Using XML to Relate New PublicObjects

<?xml version="1.0" standalone="yes"?>
<OBJECTLIST>
  <FEATURE>
    <NAME>Oracle 9iFS</NAME>
    <FOLDERPATH>/public/features</FOLDERPATH>
  </FEATURE>

  <PRODUCT>
    <NAME>Oracle9i Database Server</NAME>
    <FOLDERPATH>/public/products</FOLDERPATH>
  </PRODUCT>

  <PRODUCT>
    <NAME>Oracle9i Application Server</NAME>
    <FOLDERPATH>/public/products</FOLDERPATH>
  </PRODUCT>

  <PRODUCTFEATURERELATIONSHIP>
    <LEFTOBJECT RefType = "Path">/public/products/Oracle9i Application Server
    </LEFTOBJECT>
    <RIGHTOBJECT RefType = "Path">/public/features/Oracle 9iFS
    </RIGHTOBJECT>
    <PRICE>No additional charge.</PRICE>
  </PRODUCTFEATURERELATIONSHIP>

  <PRODUCTFEATURERELATIONSHIP>
    <LEFTOBJECT RefType = "Path">/public/products/Oracle9i Database Server
    </LEFTOBJECT>
    <RIGHTOBJECT RefType = "Path">/public/features/Oracle 9iFS
    </RIGHTOBJECT>
    <PRICE>No additional charge.</PRICE>
  </PRODUCTFEATURERELATIONSHIP>

</OBJECTLIST>

Updating Relationships

Once you have related PublicObjects, users may need to change the relationships between objects.

You can build custom applications which allow users to modify the relationships between PublicObjects by creating new relationship and deleting the old relationship, as illustrated in "Creating Relationships between PublicObjects" and "Unrelating PublicObjects". For example, if a Book is related to version 1 of a chapter, and the chapter is revised, the user can unrelate the Book from version 1 and related it to version 2 of the chapter.

A custom application could also allow Administrators to directly modify existing relationships between objects. This section describes how Administrators can directly update relationship objects.

Using XML to Update Relationships

To update a Relationship instance, the XML configuration file must:

Example 6-49 Using XML to Update Relationships

<?xml version="1.0" standalone="yes"?>
<BOOKRELATIONSHIP>
    <UPDATE RefType = "ComponentLabel">Chapter 1 : User Administration</UPDATE>   
    <LEFTOBJECT RefType = "Path">/home/guest/Manuals/AdminGuide.bk</LEFTOBJECT>
</BOOKRELATIONSHIP>
Using Java to Update Relationships

You can also update relationships with the Oracle 9iFS Java API. Each extended relationship type inherits the methods getLeftObject(), getRightObject(), and getSortSequence(), which can be used to manipulate the relationship between the PublicObjects. In addition, the inherited methods getAttribute() and setAttribute() provide a generic way to manipulate any extended attribute.

You can also implement custom Java classes to provide convenience methods for getting and setting the values for the extended attributes on your custom relationship type.



NOTE:

For instructions on implementing custom Java classes, see Chapter 17, "Customizing Content Type Behavior" 


Example 6-50 Using Java to Update Attributes on Relationships

  1. Enable Administration Mode.

    session.setAdministrationMode(true);
    
    
  2. Assume that your application has already obtained the Relationship instance

Relationship r = ......

  1. Update the SortSequence attribute on the BookRelationship instance.

    r.setAttribute("COMPONENTLABEL", 
        AttributeValue.newAttributeValue("Chapter 2 : User Administration"));
    

Unrelating PublicObjects

You can remove the relationship between PublicObjects by deleting the Relationship instance that links them.

You can remove PublicObject relationships with the Oracle 9iFS Java API as you would any other object, by calling the removeRelationship() method on the PublicObject. When this method is called, Oracle 9iFS deletes the Relationship instance. Oracle 9iFS does not support XML as a method for deleting relationships, nor does the Oracle 9iFS Manager provide a user interface for deleting Relationship instances.

Example 6-51 Using Java to Delete Relationship instances

  1. Assume that your application has already obtained the Relationship and the PublicObject.

    Relationship r = ......
    PublicObject po = .....
    
    
  2. Delete the Relationship instance.

    po.removeRelationship(r);
    

Searching for PublicObjects based on Relationships

Oracle 9iFS allows you to traverse relationships between pieces of information. You can fetch all information that has been related to a given PublicObject. Or, you can narrow your selection down to all information with a particular type of relationship to the PublicObject. For example, given a document, you could fetch all folders that contain that document. To do so, you would search for all Folders that are the LeftObject in any FolderRelationship where the document is the RightObject.

You can also search for information based on metadata about a related PublicObject. Essentially, you would construct a search that constructs a join of the PublicObject's metadata based on the Relationship object that associates them. For example, you could search for all documents that are contained in any folder that was created on June 1, 2001. To do this, you would search for all PublicObjects that are the RightObject in a FolderRelationship where the LeftObject is a Folder with the CreateDate attribute set to June 1, 2001.

Traversing Relationships

The Oracle 9iFS Java API makes it easy to traverse relationships between PublicObjects. The PublicObject class includes convenience methods, such as getLeftwardRelationshipObjects() and getRightwardRelationshipObjects(), which allow you to quickly fetch all information that is related to the object.

Example 6-52 Fetching a PublicObject's Relationships

  1. Assume that your application has already obtained the PublicObject.

    PublicObject po = .....
    
    
  2. Fetch all Relationship instances that reference the PublicObject as the LeftObject or RightObject.

    Relationship[] rightwardRels = 
           po.getRightwardRelationships("BOOKRELATIONSHIP");
    Relationship[] leftwardRels = 
           po.getLeftwardRelationships("BOOKRELATIONSHIP");
    
    
  3. Directly fetch the PublicObjects related to this PublicObject as either the LeftObject or RightObject.

    PublicObject[] rightwardObjs = 
           po.getRightwardRelationshipObjects("BOOKRELATIONSHIP");
    PublicObject[] leftwardObjs = 
           po.getLeftwardRelationshipObjects("BOOKRELATIONSHIP");
    
    
  4. For each related PublicObject, retrieve the PublicObject's name.

    AttributeValue av; // variable to hold value of a relationship attribute
    int i;
    PublicObject relPO;
    String poName;
    
    int icount = (rightwardObjs == null) ? 0 : rightwardObjs.length;
    for(i = 0; i < icount; i++)
    {
       relPO = rightwardObjs[i];
       poName = relPO.getName();
    }
    
    

The Relationship class also provides convenience methods, getLeftObject() and getRightObject(), to retrieve the related PublicObject instances from a given Relationship instance. Once you have the PublicObject, you can retrieve all of the other attributes possessed by the PublicObject and call methods to manipulate the PublicObject (e.g., getContent(), setContent()).

Example 6-53 Fetching the PublicObjects from a Relationship instance

  1. Assume that your application has already obtained the Relationship instance.

Relationship r = ......

  1. Fetch the Product from the relationship.

    PublicObject p = r.getLeftObject();
    
    
  2. Fetch the Feature from the relationship.

    PublicObject f =  r.getRightObject();
    
    
  3. Fetch metadata about the Product.

    ClassObject co = p.getClassObject(); 
    String coName = co.getName();
    Attribute[] atts = co.getEffectiveClassAttributes();
    
    AttributeValue av;
    int i, icount;
    String attName;
    
    icount = (atts == null) ? 0 : atts.length;
    for (i = 0; i < icount; i++)
    {
       attName = atts[i].getName();
       av = p.getAttribute(attName);
    }
    

Searching for PublicObjects Based on Relationships

The Oracle 9iFS Java API also allows you to construct more complex queries with Selectors and Searches. With a Selector, you can fetch all PublicObjects that pertain to a particular type of relationship. Using a Search, you can query for PublicObjects based on criteria about related PublicObjects. Example 6-54 and Example 6-55 illustrate how to search based on relationship metadata.



NOTE:

For detailed instructions on building Selectors and Searches, see Chapter 8, "Building Search Applications" 


Example 6-54 selects all books that contain a given document. To do so, the example constructs a Selector that selects all BookRelationships that reference the document as the RightObject. The example then loops through the BookRelationships to retrieve the PublicObject that is referenced as the LeftObject (i.e., the Book);

Example 6-54 Using a Selector to Find All PublicObjects that Pertain to a Given Type of Relationship


  1. Assume that your application already has obtained a Document instance.

    Document doc = ...
    
    
  2. Construct a Selector to obtain all Books that contain this document.

    Selector s = new Selector(session);
    s.setSearchClassname("BOOKRELATIONSHIP");
    s.setSearchSelection("RIGHTOBJECT = " + doc.getId());
    
    
  3. Execute the query and retrieve each BookRelationship instance that references the PublicObject as the RightObject.

    LibraryObject[] rels = s.getItems();
    
    int count = (rels == null) ? 0 : rels.length;
    for (i = 0; i < count; i++)
    Relationship br;
    PublicObject po;
    {
       br = (Relationship) rels[i];
       po = br.getLeftObject();
    }
    
    

Example 6-55 queries for all Books that contain a PublicObject whose name contains 'Work-in-progress'. To do so, the example constructs a search that selects all BookRelationships that reference a PublicObject with a name containing 'Work-in-progress' as the RightObject. The example, then loops through the resulting BookRelationships to retrieve the PublicObject that is referenced as the LeftObject (i.e., the Book).

Example 6-55 Using a Search to Find All PublicObjects Based on an Attribute of a Related PublicObject

  1. Construct a fSearchSpecification to hold the query criteria. This example does not include content criteria, so we construct an AttributeSearchSpecification.

    AttributeSearchSpecification asp = new AttributeSearchSpecification();
    
    
  2. Construct the SearchClassSpecification and set it on the AttributeSearchSpecification.

    String[] searchClasses = {"PUBLICOBJECT", "BOOKRELATIONSHIP"};
    SearchClassSpecification scp = new SearchClassSpecification(searchClasses);
    scp.addResultClass("BOOKRELATIONSHIP");
    
    asp.setSearchClassSpecification(scp);
    
    
  3. Construct a JoinQualification to join the PublicObjects that are referenced as the RightObject in a BookRelationship.

    JoinQualification jq = new JoinQualification();
    jq.setLeftAttribute("PUBLICOBJECT", null);
    jq.setRightAttribute("BOOKRELATIONSHIP", "RIGHTOBJECT");
    
    
  4. Construct an AttributeQualification to specify that the PublicObject's name contains Work-in-progress.

    AttributeQualification aq = new AttributeQualification();
    aq.setAttribute("PUBLICOBJECT", "NAME");
    aq.setOperatorType(AttributeQualification.LIKE);
    aq.setValue("%Work-in-progress%");
    
    
  5. Construct a SearchClause to combine the Join and Attribute qualifications, and require that both criteria must be satisfied. Use it to set the SearchQualification.

    SearchClause sc = new SearchClause(aq, jq, SearchClause.AND);
    asp.setSearchQualification(sc);
    
    
  6. Execute the Search and loop through the results to retrieve the LibraryObject that meet the criteria. The LibraryObjects returned will be of the content type specified in the SearchClassSpecification.

    Search srch = new Search(session, asp);
    srch.open();
    
    int i;
    LibraryObject lo;
    SearchResultObject sro = srch.next();
    PublicObject po;
    Relationship r;
    String poName;
    
    while (sro != null)
    {
        r = (Relationship) sro.getLibraryObject();
        po = r.getLeftObject(); 
        poName = po.getName();
      
        try
        {
           sro = srch.next();
        }
        catch (IfsException e)
        {
          if (e.getErrorCode() == 22000)
          {
             break;
          }
          else
          {
              e.printStackTrace();
           }
         }
    }
    
    srch.close();
    

Sample Code

Oracle 9iFS comes with a two sets of sample code files which you can use to get started working with the Java API.

Documentation Example Files

Oracle 9iFS is installed with runnable sample code files for the examples in this chapter. The sample code files are located in the <ORACLE_HOME>/9ifs/samplecode/oracle/ifs/examples/devdoc/arbitrarymetadata directory. These sample code files are useful for testing the chapter's examples. However, they must be run in the appropriate sequence and may cause naming conflicts if run more than once.

Table 6-4 lists the sample code files and their corresponding examples.


Table 6-4 Example Sample Code Files
Example  Sample Code File 

Example 6-1, "Using XML to Create Category Types" 

CreateCategoryType.xml 

Example 6-2, "Using Java to Create Category Types" 

CreateCategoryType.java 

Example 6-3, "Using Java to Add, Remove, and Update Attributes on Categories" 

UpdateCategoryType.java 

Example 6-4, "Using Java to Delete Categories" 

DeleteCategoryType.java 

Example 6-5, "Using Java to Categorize PublicObjects" 

CategorizePublicObject.java 

Example 6-6, "Using XML to Categorize New PublicObjects" 

CategorizeNewPublicObject.xml 

Example 6-7, "Using XML to Update Attributes on Category Instances" 

UpdateCategories.xml 

Example 6-8, "Using Java to Update Category Instances" 

UpdateCategories.java 

Example 6-9, "Using Java to delete Category instances" 

DeleteCategories.java 

Example 6-10, "Using a Selector to Find Specific Categories on a PublicObject" 

SelectPOCategories.java 

Example 6-11, "Using a Search to find all PublicObjects Based on a Common Category Attribute" 

SearchPOByCategory.java 

Example 6-12, "Fetching a PublicObject's Categories" 

FetchPOCategories.java 

Example 6-13, "Fetching the Associated PublicObject from a Category instance" 

FetchPOFromCategory.java 

Example 6-14, "Using XML to Create PropertyBundles" 

CreatePB.xml 

Example 6-15, "Using XML to Modify PropertyBundles" 

UpdatePB.xml 

Example 6-16, "Using Java to Create PropertyBundles" 

CreatePB.java 

Example 6-17, "Using Java to Modify PropertyBundles" 

UpdatePB.java 

Example 6-18, "Using Java to Delete PropertyBundles" 

DeletePB.java

DeleteOrphanedPBs.java

DeleteOrphanedPBValueDefaults.java

DeleteOrphanedPBValueDefaultPBs.java 

Example 6-19, "Using XML to Apply a New PropertyBundle to a New Content Type" 

ApplyNewPBtoNewCT.xml 

Example 6-20, "Using XML to Apply a Preexisting PropertyBundle to a New Content Type" 

ApplyExistingPBtoNewCT.xml 

Example 6-21, "Using XML to Apply a Preexisting PropertyBundle to a Preexisting Content Type" 

ApplyExistingPBtoExistingCT.xml 

Example 6-22, "Using XML to Apply a Preexisting PropertyBundle to a New Folder" 

ApplyExistingPBtoNewPO.xml 

Example 6-23, "Using XML to Apply an Existing PropertyBundle to an Existing Folder" 

ApplyExistingPBtoExistingPO.xml 

Example 6-24, "Using Java to Apply a New PropertyBundle to a New Content Type" 

ApplyNewPBtoNewCT.java 

Example 6-25, "Using Java to Apply a PropertyBundle to a Preexisting Content Type" 

ApplyExistingPBtoExistingCT.java 

Example 6-26, "Using Java to Apply a PropertyBundle to a New Folder" 

ApplyExistingPBtoNewPO.java 

Example 6-27, "Using a Selector to Fetch Properties" 

SelectProperties.java 

Example 6-28, "Using a Search to Find all PublicObjects Based on Common Property Data" 

SearchPOByPB.java 

Example 6-29, "Using XML to Create PolicyPropertyBundles" 

CreatePPB.xml 

Example 6-30, "Using XML to Add Policies to PolicyPropertyBundles" 

AddPolicytoPPB.xml 

Example 6-31, "Using XML to Remove Policies from PolicyPropertyBundles" 

RemovePolicyfromPPB.xml 

Example 6-32, "Using XML to Modify Policies" 

UpdatePolicy.xml 

Example 6-33, "Using Java to Create PolicyPropertyBundles" 

CreatePPB.java 

Example 6-34, "Using Java to Modify PolicyPropertyBundles" 

UpdatePPB.java 

Example 6-35, "Using Java to Delete PolicyPropertyBundles" 

DeletePPB.java

DeleteOrphanedPPBValueDefaults.java

DeleteOrphanedPPBValueDefaultPBs.java

DeleteOrphanedPPBs.java

DeleteOrphanedPolicies.java 

Example 6-36, "Using XML to Apply a New PolicyPropertyBundle to a New Content Type" 

ApplyNewPPBtoNewCT.xml 

Example 6-37, "Using XML to Apply a Preexisting PropertyBundle to a New Content Type" 

ApplyExistingPPBtoNewCT.xml 

Example 6-38, "Using XML to Apply a Preexisting PropertyBundle to a Preexisting Content Type" 

ApplyExistingPPBtoExistingCT.xml 

Example 6-39, "Using Java to Apply a New PolicyPropertyBundle to a New Content Type" 

ApplyNewPPBtoNewCT.java 

Example 6-40, "Using Java to Apply a PolicyPropertyBundle to a Preexisting Content Type" 

ApplyExistingPPBtoExistingCT.java 

Example 6-41, "Using Java to Apply a PolicyPropertyBundle to a New Folder" 

ApplyExistingPPBtoNewPO.java 

Example 6-42, "Using XML to Create Relationship Types" 

CreateRelationshipType.xml 

Example 6-43, "Using Java to Create Relationship Types" 

CreateRelationshipType.java 

Example 6-44, "Using Java to Add, Remove, and Update Attributes on Relationship Types" 

UpdateRelationshipType.java 

Example 6-45, "Using Java to Delete Relationship Types" 

DeleteRelationshipType.java 

Example 6-46, "Using Java to Relate PublicObjects" 

RelatePublicObjects.java 

Example 6-47, "Using XML to Relate PublicObjects" 

RelateExistingPublicObjects.xml 

Example 6-48, "Using XML to Relate New PublicObjects" 

RelateNewPublicObjects.xml 

Example 6-49, "Using XML to Update Relationships" 

UpdateRelationship.xml 

Example 6-50, "Using Java to Update Attributes on Relationships" 

UpdateRelationships.java 

Example 6-51, "Using Java to Delete Relationship instances" 

DeleteRelationships.java 

Example 6-52, "Fetching a PublicObject's Relationships" 

FetchPORelationships.java 

Example 6-53, "Fetching the PublicObjects from a Relationship instance" 

FetchPOFromRelationship.java 

Example 6-54, "Using a Selector to Find All PublicObjects that Pertain to a Given Type of Relationship" 

SelectPOByRelationshipType.java 

Example 6-55, "Using a Search to Find All PublicObjects Based on an Attribute of a Related PublicObject" 

SearchPOByRelatedPO.java 

Running the Java Sample Code Files

To run the Java sample code files, follow these steps:

  1. Ensure that the CLASSPATH on the Oracle 9iFS host machine includes the Java API jar files.

  2. With JDK 1.2.2, compile the sample code file in the <ORACLE_HOME>/9ifs/samplecode/oracle/ifs/examples/devdoc/arbitrarymetadata directory.

Example 6-56 Compiling the Sample Code Files on Solaris

> cd $ORACLE_HOME/9ifs/samplecode/oracle/ifs/examples/devdoc/arbitrarymetadata
> javac CreatePPB.java

  • Check the file comments to determine if the file expects other files to be run beforehand.

  • Run the class and supply the arguments. The input values for the arguments will be displayed. All arguments must have a value. Some or all arguments will be defaulted if unspecified. The class will print the results to the screen.

    Example 6-57 Running the Sample Code Files on Solaris

    > java oracle.ifs.examples.devdoc.arbitrarymetadata.CreatePPB.java
    
      Running with arguments :
        user = system
        password = manager
        service = IfsDefault
        schemapassword = ifssys
      -----------Results----------
    Policy created : FaxPolicy
     for operation : SendByFax
     with implementation : MyCompany.MyApp.DeliveryServers.FaxServer
    Policy created : PrintPolicy
     for operation : SendByPrinter
     with implementation : MyCompany.MyApp.DeliveryServers.PrintServer
    PolicyPropertyBundle created : Delivery Policies PolicyPropertyBundle
    ValueDefaultPropertyBundle created : DeliveryPoliciesValueDefaultPropertyBundle
    Value Default created : DeliveryPoliciesValueDefault
    

    Running the XML Sample Code Files

    To run the XML configuration files, follow these steps:

    1. Open an Oracle 9iFS client which supports parsing XML configuration files.

    2. Login as a user with the appropriate administration privileges for the task performed by the XML configuration file.

    3. Import the XML configuration file.

    4. View the results with Oracle 9iFS Manager.

    API Sample Code

    In addition to the example sample code files, Oracle 9iFS is installed with more advanced sample code that helps you get started working with the Java API. The API sample code is located in the <ORACLE_HOME>/9ifs/samplecode/api directory. This API sample code is easier to work with than the Documentation sample code files because you can run the samples over and over without naming conflicts.

    Table 6-5 lists the API sample code that is relevant to this chapter.


    Table 6-5 API Sample Code
    Class  Usage 

    CategorySample.java 

    Creates Documents with Categories. 

    PropertyBundleSample.java 

    Creates a PropertyBundle. Adds, updates, and removes Properties in the PropertyBundle. 


  • Go to previous page Go to next page
    Oracle
    Copyright © 2001 Oracle Corporation.

    All Rights Reserved.
    Go To Table Of Contents
    Contents
    Go To Index
    Index