This section provides information about working with object stores and contains illustrative Java™ and C# code samples.
You can get a reference to an ObjectStore
object by iterating an ObjectStoreSet
collection. You can create an instance of ObjectStore
by:
createInstance
, getInstance
, or fetchInstance
on the Factory.ObjectStore
class. getObjectStore
on an instance of a RepositoryObject
subclass.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). The code 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); } }
Object stores are typically created by a system administrator using the FileNet Enterprise Manager administrative tool built into Content Engine. However, you can use factory methods as described in this section to create object stores. Prerequisites to creating an object store, whether through FileNet Enterprise Manager or programmatically, are creating a database; configuring connection pools and data sources in the application server to connect to the database; defining object store administrative users and groups defined; and defining general users and groups of the object store. Code samples in this section assume that these prerequisites have been satisfied.
createInstance method
To create a new instance of an ObjectStore
object, call Factory.ObjectStore.createInstance
. 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 pre-defined set of administrative users and groups (for example, "Domain Admins") who can access the returned ObjectStore
object; a pre-defined 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 four properties: DisplayName, SymbolicName, JNDIDataSource (the local JNDI datasource name), and JNDIXADataSource (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" String jndiSource, // JNDI data source. Example: "myJndiDataSource" 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_JNDIDataSource(jndiSource); objStore.set_JNDIXADataSource(jndiXASource); // 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" String jndiSource, // Example: "myJndiDataSource" String jndiXASource // Example: "myJndiXADataSource" 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.JNDIDataSource = jndiSource; objStore.JNDIXADataSource = jndiXASource; // 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); }
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 sub class 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 sub class 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); }
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 wish 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.
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" { // 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(AccessLevel.FULL_CONTROL_OBJECT_STORE_AS_INT)); // 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" { // Create a new access permission object IAccessPermission ap = Factory.AccessPermission.CreateInstance(); // Set access permissions ap.GranteeName = granteeName; ap.AccessType = AccessType.ALLOW; ap.AccessMask = (Int32)AccessLevel.FULL_CONTROL_OBJECT_STORE; // Set and save the new permissions IObjectStore objStore = Factory.ObjectStore.FetchInstance(domain, objStoreName, null); objStore.Permissions.Add(ap); objStore.Save(RefreshMode.REFRESH); }
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 in "Full Control" levels of object store access. After granting the access right, 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:
AccessRight.PRIVILEGED_WRITE
permission to ordinary users or groups or even to most administrators. You must explicitly grant this access right, and you should grant it only to those users or groups who need this special kind of access. 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.PRIVILEGED_WRITE_AS_INT + AccessLevel.FULL_CONTROL_OBJECT_STORE_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); // 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()); }
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 = (Int32)AccessRight.PRIVILEGED_WRITE + (Int32)AccessLevel.FULL_CONTROL_OBJECT_STORE; // 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); }
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.
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)
…