IBM FileNet P8, Version 5.2            

Working with Object Stores

This section provides information about working with object stores and contains illustrative Java™ and C# code samples.

Instantiating an ObjectStore Object

You can get a reference to an ObjectStore object by iterating an ObjectStoreSet collection. You can create an instance of ObjectStore by:

Instantiating an ObjectStore Object from a Domain

The following code example retrieves an ObjectStoreSet collection object from the Domain object. The returned collection contains elements that represent each object store defined by the Global Configuration Data (GCD). For information about the GCD, see the FileNet® P8 Domain topic in Getting Started. The code sample iterates through the collection, retrieving individual ObjectStore objects, and, by retrieving the value of the DisplayName property, returns the name of each ObjectStore object in the collection.

Java Example

// Instantiate object store from domain.
public static void instantiateObjectStoreFromDomain(
        Connection conn,
        String domainName)      // Example: "Domain1"
{
    // Get domain.
    Domain domain = Factory.Domain.fetchInstance(
                           conn, domainName, null);
    ObjectStoreSet osColl =  domain.get_ObjectStores();
                
    // Get each object store.
    Iterator iterator = osColl.iterator();
    while(iterator.hasNext())
    {
        // Get next object store.
        ObjectStore objStore = (ObjectStore)iterator.next();
                        
        // Get the display name of the object store.
        String objStoreName = objStore.get_DisplayName();
        System.out.println("Object store name = " + objStoreName); 
    }
}
    

C# Example

// Instantiate object store from domain.
public static void InstantiateObjectStoreFromDomain(
IConnection conn, String domainName)  // Example: "Domain1"
{
    // Get domain.
    IDomain domain = Factory.Domain.FetchInstance(
                            conn, domainName, null);
    IObjectStoreSet osColl = domain.ObjectStores;

    // Get each object store.        
    foreach (IObjectStore objSstore in osColl)
    {
        // Get the display name of the object store.
        String objStoreName = objStore.DisplayName;
        Debug.WriteLine("Object store name = " + objStoreName); 
    }
}

Instantiating an ObjectStore Object using Factory methods

Object stores are typically created and maintained by a system administrator using the Administration Console for Content Platform Engine. But a custom application can be built to manage object stores as well. You use the API factory methods to create or retrieve object stores.

Note that administrative prerequisites must be met to support object store creation. The following tasks are typically performed by the database and application server administrators:

createInstance method

You create a new instance of an ObjectStore object with the Factory.ObjectStore.createInstance call. This method instantiates a local ObjectStore object. The ObjectStore object does not exist in the GCD until a round trip to the server happens at a later commit (save) step. The save step can be an explicit call to the save method or via a batch operation.

Input parameters to this method are the following: a Domain object; a predefined set of administrative users and groups (for example, "Domain Admins") who can access the returned ObjectStore object; a predefined set of non-administrative security principals (users and groups, for example, "Domain Users") who can access the returned ObjectStore object; and, optionally, a customized schema script. After creating the object instance, you must set the following properties: DisplayName, SymbolicName, and DatabaseConnection. The DatabaseConnection property is set to a CmDatabaseConnection object, which defines the local JNDI datasource name and the transaction JNDI datasource name. You can set additional properties as needed.

Prior to object store creation, you can also set the properties that control the storage locations of various database objects. Doing so causes the appropriate database statements to be issued such that those database objects are appropriately located. The following properties control database object storage locations:

Important: Setting the DatabaseXXXStorageLocation properties AFTER the object store has been created only affects database locations of objects (that is, tables, indexes, or LOB columns) that are subsequently created.

In addition, you can call a different form of the createInstance method that takes a schema script. By using a customized schema script, a Database Administrator (DBA) can make modifications to the object store database schema. The DBA can obtain a factory generated script relative to the database type by accessing the corresponding property on the Domain object. The properties are named ObjectStoreSchemaDB2, ObjectStoreSchemaMSSQL, and ObjectStoreSchemaOracle, and their values contain the factory generated schema for an object store corresponding to the database vendor indicator. This approach overrides the values set by the DatabaseXXXStorageLocation properties during object store creation.

In the code fragments below, a connection (conn) is assumed to already have been established. The code retrieves the domain and then creates an ObjectStore object that represents ObjectStore1. The example provides an option to create the object store with a customized schema script.

Java Example

// Create an object store instance.
public static void createObjectStoreInstance(
    Connection conn,
    String[] adminName,   // Example: "Domain Admins, CEMPAdmin"
    String[] userName,    // Example: "Domain Users, CEMPUser"
    CmDatabaseConnection dbConn,   // Defines the data sources
    String objStoreName,  // Object store name. Example: "ObjectStore1"
    String scriptPath)    // Creation script file path. Example: "C:\os_script.txt"
        
    throws Exception {
            
        // Get the default domain.
        Domain domain = Factory.Domain.getInstance(conn, null);

        // Create an object store.
        String[] admins = {adminName};
        String[] users = {userName};
        ObjectStore objStore = null;
                
        if (scriptPath == null) {
            // Create without using a schema script.
            System.out.println("Creating object store without a schema script");
            objStore = Factory.ObjectStore.createInstance(
                              domain, admins, users);
        } 
        else {
            // Create using a schema script.
            // The getScript method reads in the script from a file.
            String creationScript = getScript(scriptPath);
            System.out.println("Creating object store with a schema script");
                        
            // To print the contents of the script file, uncomment the next line.
            // System.out.println(creationScript); 
            objStore = Factory.ObjectStore.createInstance(
                              domain, admins, users, creationScript);                   
        }

        // Set properties.
        objStore.set_DisplayName(objStoreName);
        objStore.set_SymbolicName(objStoreName);
        objStore.set_DatabaseConnection(dbConn);
  
        // Save object store and display name.
        objStore.save(RefreshMode.REFRESH);
        System.out.println("Object store name: " +  objStore.get_Name()); 
    }
    

C# Example

// Create an object store instance.
public static void CreateObjectStoreInstance(
    IConnection conn,
    String[] adminName,    // Example: "Domain Admins, CEMPAdmin"
    String[] userName,     // Example: "Domain Users, CEMPUser"
    ICmDatabaseConnection dbConn,   // Defines the data sources
    String objStoreName,   // Object store name. Example: "ObjectStore1"
    String scriptPath)     // Creation script file path. Example: "C:\os_script.txt"
                
    // Get the default domain.
    {IDomain domain = Factory.Domain.GetInstance(conn, null);
  
        // Create an object store.         
        String[] admins = {adminName};
        String[] users = {userName};
        IObjectStore objStore = null;
                
        if (scriptPath == null) {
            // Create without using a schema script.
            Debug.WriteLine ("Creating object store without a schema script");
            objStore = Factory.ObjectStore.CreateInstance(
                              domain, admins, users);
        }
        else {          
            // Create using a schema script.       
            // The GetScript method reads in the script from a file. 
            String creationScript = GetScript(scriptPath);
            Debug.WriteLine("Creating object store with a schema script");
                        
            objStore = Factory.ObjectStore.CreateInstance(
                              domain, admins, users, creationScript);
        }
                         
        // Set properties.
        objStore.DisplayName = objStoreName;
        objStore.SymbolicName = objStoreName;
        objStore.DatabaseConnection = dbConn;

        // Save object store and display name.
        ojbStore.Save(RefreshMode.REFRESH);   
        Debug.WriteLine("Object store name: " +  objStore.Name); 
    }
    

getInstance method

You can construct a local instance of the ObjectStore class by calling Factory.ObjectStore.getInstance. This method does not verify the existence of the requested object on the server; it returns a local reference to the object, which is not affiliated with a server object until you perform a function on the object (for example, fetch a property value) that causes a round trip to the server. This technique, also called "fetchless instantiation", is useful when the desired object will only serve passively, for example, as the target value of an object-valued property. The code fragment below instantiates an ObjectStore object in this manner:

Java Example

// Get object store instance.
static void getObjectStoreInstance(
        Domain domain,
        String objStoreName)    // Example: "ObjectStore1"
 {
    // Get object store (fetchless instantiation).
    ObjectStore ojbStore = Factory.ObjectStore.getInstance(domain, objStoreName);

    // Show object store name.
    objStore.refresh();
    System.out.println("Object store name: " + objStore.get_Name());                    
 }
    

C# Example

// Get object store instance.
static void GetObjectStoreInstance(
        IDomain domain,
        String objStoreName)   // Example: "ObjectStore1"
{            
    // Get object store (fetchless instantiation).
    IObjectStore objStore = Factory.ObjectStore.GetInstance(domain, objStoreName);

    // Show object store name.
    objStore.Refresh();
    Debug.WriteLine("Object store name: " + objStore.Name); 
}
    

fetchInstance method

To retrieve a particular ObjectStore object from the server, call Factory.ObjectStore.fetchInstance. This method makes a round trip to the server to retrieve the property values of the ObjectStore object. You can limit the number of properties that are returned by using a property filter as shown in the code samples below. 

Java Example

// Get object store instance.
static void fetchObjectStoreInstance(
        Domain domain,
        String objStoreName)    // Example: "ObjectStore1"
{
    // Define a property filter to limit the returned properties.
    PropertyFilter filter = new PropertyFilter(); 
    filter.addIncludeProperty(0, null, null,
                              PropertyNames.ROOT_CLASS_DEFINITIONS, null); 
    filter.addIncludeProperty(0, null, null, 
                              PropertyNames.DISPLAY_NAME, null); 
          
    // Fetch object store using the property filter.            
    ObjectStore objStore = Factory.ObjectStore.fetchInstance(
                                  domain, objStoreName, filter);

    // Show object store display name.
    System.out.println("Object store name: " + objStore.get_DisplayName());                   
}
    

C# Example

// Get object store instance.
static void FetchObjectStoreInstance(
            IDomain domain,
            String objStoreName)    // Example: "ObjectStore1"
{
    // Define a property filter to limit the returned properties.
    PropertyFilter filter = new PropertyFilter(); 
    filter.AddIncludeProperty(0, null, null,
                              PropertyNames.ROOT_CLASS_DEFINITIONS, null); 
    filter.AddIncludeProperty(0, null, null, 
                              PropertyNames.DISPLAY_NAME, null); 
  
    // Fetch object store using the property filter.
    IObjectStore objStore = Factory.ObjectStore.FetchInstance(
                                   domain, objStoreName, filter); 

    // Show object store display name.
    Debug.WriteLine("Object store name: " + objStore.DisplayName);     
}
    

Instantiating anObjectStore Object from a RepositoryObject subclass

A RepositoryObject is any object that can be stored in an object store (such as Document, Folder, Annotation, and so on). The getObjectStore method of the RepositoryObject interface returns the object store to which an object belongs, as shown in the code fragments below:

Java Example

  
// Get object store from repository object subclass.
private static void getObjectStoreFromSubclass(
    Document doc)  // Get a document using your own approach, for example, from a collection.
{
    // Get the object store in which the document is stored. 
    ObjectStore objStore = doc.getObjectStore();

    // Get the display name of the returned object store.
    objStore.refresh();
    System.out.println("Object store name = " + objStore.get_DisplayName()); 
}
    

C# Example

// Get object store from repository object subclass.
private static void GetObjectStoreFromSubclass(
    IDocument doc)  // Get a document using your own approach, for example, from a collection.
{

    // Get the object store in which the document is stored. 
    IObjectStore objStore = doc.GetObjectStore();

    // Get the display name of the returned object store.
    objStore.Refresh();  
    Debug.WriteLine("Object store name = " + objStore.DisplayName); 
}
    

Installing an AddOn Object on the Object Store

Before you can install an addon to an object store, you must first create and save it, which automatically registers it in the IBM® FileNet P8 Global Configuration Data (GCD) database of a domain. Once an addon is registered, you can install it to a new or existing object store.

To install a registered AddOn or UpgradeAddOn object, use the installAddOn method on the ObjectStore interface. Input to this method is the registered object you want to install. For a code sample that illustrates how to retrieve the installable addons from the domain and select one for installation, refer to Working with Addon-Related Objects.

Setting Object Store Access Rights

The permissions (access rights) associated with an object store control the degree of access that users have to the objects within the object store. In the example below, user "CEMPAdmin" is granted full control to work with documents in this object store. Granting full control means that the specified user is granted permission to connect to the object store, store objects, modify objects, and remove objects. (For additional examples, see Setting Permissions.)

Java Example

// Set access rights.
public static void setAccessRights(
    Domain domain,
    String granteeName,     // Example: "CEMPAdmin"
    String objStoreName)    // Example: "ObjectStore1"
{

    final int ACCESS_REQUIRED = AccessRight.WRITE_ANY_OWNER.getValue() |
    AccessRight.REMOVE_OBJECTS.getValue() |  AccessRight.STORE_OBJECTS.getValue() |
    AccessRight.CONNECT.getValue() | AccessRight.WRITE_ACL.getValue() |
    AccessRight.READ_ACL.getValue() | AccessRight.MODIFY_OBJECTS.getValue();

    // Create a new access permission object.
    AccessPermission ap = Factory.AccessPermission.createInstance();

    // Set access permissions.  
    ap.set_GranteeName(granteeName);
    ap.set_AccessType(AccessType.ALLOW);
    ap.set_AccessMask(new Integer(ACCESS_REQUIRED)); 

    // Set and save the new permissions.
    ObjectStore objStore = Factory.ObjectStore.fetchInstance(domain, objStoreName, null);
    AccessPermissionList apl = objStore.get_Permissions();
    apl.add(ap);
    objStore.set_Permissions(apl); 
    objStore.save(RefreshMode.REFRESH);
}
        

C# Example

// Set access rights.
public static void SetAccessRights(
    IDomain domain,
    String granteeName,     // Example: "CEMPAdmin"
    String objStoreName)    // Example: "ObjectStore1"
{
    const int ACCESS_REQUIRED = (int)AccessRight.WRITE_ANY_OWNER |
    (int)AccessRight.REMOVE_OBJECTS |  (int)AccessRight.STORE_OBJECTS |
    (int)AccessRight.CONNECT | (int)AccessRight.WRITE_ACL |
    (int)AccessRight.READ_ACL | (int)AccessRight.MODIFY_OBJECTS;

    // Create a new access permission object.
    IAccessPermission ap = Factory.AccessPermission.CreateInstance();

    // Set access permissions.  
    ap.GranteeName = granteeName;  
    ap.AccessType = AccessType.ALLOW;
    ap.AccessMask = (Int32)ACCESS_REQUIRED;

    // Set and save the new permissions.
    IObjectStore objStore = Factory.ObjectStore.FetchInstance(domain, objStoreName, null);    
    objStore.Permissions.Add(ap);
    objStore.Save(RefreshMode.REFRESH);        
}

Setting Privileged Write Access on an Object Store

To users who run system-level tools, such as import/export, migration applications, and federation tools, and who therefore require the ability to modify certain system-level properties, you must explicitly grant Privileged Write access (AccessRight.PRIVILEGED_WRITE). This access right is not included as a standard right for administrative access to an object store. After granting the Privileged Write access, an application can make calls to change the system-level properties. (For conceptual information about privileged write access and system-level properties, see the Security topic.)

Important:

The code snippet below sets privileged write access on the object store, allowing a special administrative user the right to modify system-level properties on a document. The special user is allowed to set the document properties to reflect original creator, create date, and modification information.

Java Example

// Set write access.
private static void setWriteAccess(
    ObjectStore objStore,    
    String granteeName,
    String granteePassword,
    String originalCreator,
    Date originalCreateDate,
    String originalModifier,
    Date originalModifyDate)
{
    // Create a new access permission object.
    AccessPermission ap = Factory.AccessPermission.createInstance();

    // Set access permissions  
    ap.set_GranteeName(granteeName);  
    ap.set_AccessType(AccessType.ALLOW);
    ap.set_AccessMask( 
        new Integer(AccessRight.WRITE_ANY_OWNER_AS_INT + AccessRight.REMOVE_OBJECTS_AS_INT +
        AccessRight.MODIFY_OBJECTS_AS_INT + AccessRight.STORE_OBJECTS_AS_INT + AccessRight.CONNECT_AS_INT +
        AccessRight.WRITE_ACL_AS_INT + AccessRight.READ_ACL_AS_INT + AccessRight.PRIVILEGED_WRITE_AS_INT));

    // Add the permission to the list for the Object Store.
    objStore.get_Permissions().add(ap);            
            
    // Save the object store with its permissions.
    objStore.save(RefreshMode.REFRESH);
            
    // Login in as the user who has the newly granted
    // privileged write access.
    Connection conn = objStore.getConnection();
    Subject sub = UserContext.createSubject(conn, granteeName, granteePassword, "FileNetP8");
    UserContext.get().pushSubject(sub);
    try
    {
        // Create a document "doc".
        Document doc = Factory.Document.createInstance(objStore, "Document");
            
        // Set system-level properties on the created document "doc". 
        doc.set_Creator(originalCreator);
        doc.set_DateCreated(originalCreateDate);
        doc.set_LastModifier(originalModifier);
        doc.set_DateLastModified(originalModifyDate);
            
        // Perform additional actions as desired.
            
        // Save the document.            
        doc.save(RefreshMode.REFRESH);
        System.out.println("Document created: " +  doc.get_Id());
    }
    finally
    {
        UserContext.get().popSubject();
    }
}
    

C# Example

// Set write access.
private static void SetWriteAccess(
    IObjectStore objStore,
    String granteeName,
    String granteePassword,
    String originalCreator,
    DateTime originalCreateDate,
    String originalModifier,
    DateTime originalModifyDate)
{
    // Create a new access permission object.
    IAccessPermission ap =
        Factory.AccessPermission.CreateInstance();

    // Set access permissions.  
    ap.GranteeName = granteeName;
    ap.AccessType = AccessType.ALLOW;
    ap.AccessMask = (int)AccessRight.WRITE_ANY_OWNER + (int)AccessRight.REMOVE_OBJECTS +
        (int)AccessRight.MODIFY_OBJECTS + (int)AccessRight.STORE_OBJECTS + (int)AccessRight.CONNECT +
        (int)AccessRight.WRITE_ACL + (int)AccessRight.READ_ACL + (int)AccessRight.PRIVILEGED_WRITE;

    // Set permissions.
    objStore.Permissions.Add(ap);

    // Save the object store with its permissions.
    objStore.Save(RefreshMode.REFRESH);

    // Login in as user with newly granted write access.
    UsernameToken token = new UsernameToken(granteeName, granteePassword, PasswordOption.SendPlainText);
    UserContext.SetThreadSecurityToken(token);
            
    // Create a document "doc".
    IDocument doc = Factory.Document.CreateInstance(objStore, "Document");

    // Set system-level properties.
    doc.Creator = originalCreator;
    doc.DateCreated = originalCreateDate;
    doc.LastModifier = originalModifier;
    doc.DateLastModified = originalModifyDate;

    // Perform additional actions as desired.

    // Save the document.
    doc.Save(RefreshMode.REFRESH);
    Debug.WriteLine("Document created: " + doc.Id);
}
    

Avoid read-only exception on update

If you subsequently fetch the document object with the intent of modifying its LastModifier or DateLastModified property values again, another step is required. In this scenario, you might subsequently fetch the document object with a filter specifying (directly or indirectly) the LastModifier or DateLastModified property and update those property values. When you call save, a client side read-only exception is thrown. To avoid the exception, prior to updating the property values and calling save, you must call removeFromCache to remove LastModifier and DateLastModified properties from the local property cache.

Working with Custom Schema Scripts

You can create an object store specifying a customized schema script by calling the Factory.ObjectStore.createInstance(domain, admins, users, schemaScript) method. By using a customized schema script, you can get finer grained control of storage locations for object store tables, indexes, and LOB columns than you can get by using the ObjectStore object's default database storage locations.

Your customized schema script should be derived from one of the default (factory generated) scripts available via the ObjectStoreSchemaXXX properties, where XXX is DB2, MSSQL, or Oracle. The schema script must also contain the correct version information. The version information in the header of the script must correspond to the Content Engine's schema revision level indicator, which is stored in the ObjectStore database's DDState.schema_revision_string column. When the script is retrieved via the Domain level property, it contains the correct revision level. However, in rare circumstances (usually involving an upgrade to the server after the script was retrieved), the schema revision string stored in the database might not match the revision information in the schema script header. Content Engine will not process the script if this indicator does not match the schema revision level expected by the Content Engine server and an exception will be generated. The following text is an example of the version information found in the script header (the generation date and revision number will be different in your environment):

-- Generated for SQL Server databases on: Wed Apr 02 11:11:30 PDT 2008
-- The following SchemaRevision comment must be present and must correspond to
-- the proper schema revision level at the time the ObjectStore is created.
-- SchemaRevision: 14.1.14
Important: When customizing the script, do not alter any of the names and structures of existing tables, indexes, or columns. Doing so will cause system failures.

Note that the DB2 for z/OS script is available from the ObjectStoreSchemaDB2 property when the GCD is configured against a DB2 for z/OS database. When modifying the default database scripts, be aware that the DB2 for z/OS script differs significantly from the scripts for DB2 on LUW, MSSQL, and Oracle, including the use of substitution placeholders. Each substitution variable is surrounded by a question mark character (?) and the variable name corresponds to a string-valued custom property name specified during WebSphere® Application Server configuration. The following excerpt shows how this variable is used within the script (the ellipses in this example indicate additional statements that have been deleted for brevity):

CREATE TABLE DocVersion(object_id varchar(16) for bit data NOT NULL PRIMARY KEY , 
object_class_id varchar(16) for bit data NOT NULL , security_id varchar(16) for bit data NOT NULL ,
… , security_folder_id varchar(16) for bit data ) IN DATABASE ?zOSDatabaseName?
CREATE INDEX I_DocVersion22 ON DocVersion (version_series_id, major_version_number DESC, minor_version_number DESC)  
USING STOGROUP ?zOSDefaultSTOGROUP? ?zOSSTOGROUPOptions?
…

Compare the example above with the MSSQL script excerpt below (the ellipses indicate additional statements that have been deleted for brevity):

CREATE TABLE DocVersion(object_id uniqueidentifier NOT NULL PRIMARY KEY , object_class_id
uniqueidentifier NOT NULL , security_id uniqueidentifier NOT NULL , … , security_folder_id uniqueidentifier )
CREATE INDEX I_DocVersion22 ON DocVersion (version_series_id, major_version_number DESC, minor_version_number DESC)
…


Feedback

Last updated: October 2013
objectstore_procedures.htm

© Copyright IBM Corporation 2014.
This information center is powered by Eclipse technology. (http://www.eclipse.org)