| Oracle Internet File System Developer Reference Release 9.0.1.1.0 Part Number A90093-02 |
|
This chapter explains how to customize the behavior of content types. The chapter covers the following topics:
As discussed in Chapter 5, "Extending Content Types and Attributes", when you create custom content types, they automatically inherit the behaviors of the content types they extend. Without having to do any Java programming, you can leverage all of the content management capabilities built into Oracle 9iFS for custom types of information. Application users will be able to parse, render, and manage the life cycle of instances of the custom content type with any of the clients and protocols servers that come with Oracle 9iFS out of the box.
As discussed in Chapter 3, "Java API Overview", every out-of-the-box content type possesses a set of Java classes that implement its behavior. Behaviors, such as converting a document to HTML or generating a summary of the document, are implemented via methods on these Java classes.
To customize content type behavior, you can extend the bean-side and server-side Java classes. You can create extended bean-side Java classes to allow applications to access custom attributes and behaviors implemented for a content type. You can extend the server-side Java class for a content type to modify how Oracle 9iFS performs certain operations, such as insert, update, and delete.
As illustrated in Table 17-1, the bean-side and server-side Java classes parallel the content type hierarchy. For example, S_PublicObject.class implements the behavior of the PublicObject content type. The S_Document.class implements the behavior of the Document content type. Just as the Document content type extends the PublicObject type to inherit the PublicObject type's attributes, S_Document.class extends S_PublicObject.class to inherit its methods and add new methods that pertain to the Document content type.
Between each content type's bean-side and server-side Java class is a Tie class. Tie classes are placeholders for inserting custom code at any point in the class hierarchy, without modifying the out-of-the-box Java classes.
When you create a custom content type, you do not have to implement custom Java classes. Your custom content type will automatically be associated with the Java class of the content type that it extends. For example, when you create a custom content type, Image, that extends the Document content type, Oracle 9iFS automatically uses Document.class and S_Document.class to implement the behavior of the Image content type.
You can extend the Oracle 9iFS Java classes to implement custom behavior for content types. You can extend the Java API in three ways:
The following are some recommended practices when implementing custom Java classes:
Extending behavior is a complex task. We recommend that you postpone tackling custom Java Beans, server overrides, and Tie classes until you have had considerable experience with Oracle 9iFS and its Java API. Specifically, we suggest that your background should include knowledge and hands-on experience in the following areas:
The bean-side Java classes in the Oracle 9iFS Java API provide the primary interface for applications to create and retrieve information, get and set attributes and content, and traverse relationships. When you create a custom content type, applications can use the Oracle 9iFS beans-side Java classes to manipulate instances of the content type. For example, to get and set custom attributes, the application can call the getAttribute() and setAttribute() methods on the LibraryObject class. To create new instances of a custom content type, the application can call the getAttributeByUpperCaseName() and setAttributeByUpperCaseName()methods on LibraryObjectDefinition.
You can extend the bean-side Java classes to provide methods that make it easier for applications to manipulate information. For example, you can implement convenience methods for getting and setting custom attributes, such as getImageWidth() and setImageWidth(). You can implement methods that create and retrieve custom relationships that are used to construct complex content types, such as getBookComponents().
To implement a custom bean-side Java class, follow these steps:
You must first include a class declaration. The bean-side class should extend the bean-side Tie class of the content type that your custom content type extends (e.g., Document). Put your class into a new custom package, such as MyCompany.MyApp.beans. (Do not add this class to the oracle.ifs.beans package.)
public class Image extends TieDocument
The bean-side Java class must implement a constructor that calls the constructor for its superclass. Table 17-2 lists the parameters for the constructor.
public Image(LibrarySession session, Long id, Long classID, S_LibraryObjectData data) throws IfsException { super(session, id, classID, data); }
The bean-side Java class provides the primary interface for applications to work with your content type. You should implement methods that make the content type's custom attributes and behavior accessible to a client application. For example, you can implement convenience methods for getting and setting the custom attributes on your content type.
public void setImageWidth(int newValue) throws IfsException { AttributeValue av = AttributeValue.newAttributeValue(newValue); setAttribute("WIDTH", av); } public void setImageHeight(int newValue) throws IfsException { AttributeValue av = AttributeValue.newAttributeValue(newValue); setAttribute("HEIGHT", av); } public int getImageWidth(LibrarySession session) throws IfsException { AttributeValue av = getAttribute("WIDTH"); int width = av.getInteger(session); return width; } public int getImageHeight(LibrarySession session) throws IfsException { AttributeValue av = getAttribute("HEIGHT"); int height = av.getInteger(session); return height; }
You can also include methods that perform processing tasks. For example, you might provide a method that derives data by performing mathematical functions on an instance's attribute values. Or, you might provide a method that retrieves all documents that are related to another document.
public PublicObject[] getBooks(LibrarySession session) throws IfsException { PublicObject[] relObjs = sel.getLeftwardRelationshipObjects("BOOK_RELATIONSHIP"); return relObjs; }
|
NOTE: Example 17-4 uses a Selector to get the Books that include the Image. See Chapter 8, "Building Search Applications" for instructions on how to use Selectors. |
The following example provides the complete sample code for a bean-side Java class for the custom content type Image.
package MyCompany.MyApp.beans; import oracle.ifs.beans.LibrarySession; import oracle.ifs.beans.TieDocument; import oracle.ifs.common.AttributeValue; import oracle.ifs.common.IfsException; import oracle.ifs.server.S_LibraryObjectData; public class Image extends TieDocument { public Image(LibrarySession session, Long id, Long classID, S_LibraryObjectData data) throws IfsException { super(session, id, classID, data); } public void setImageWidth(int newValue) throws IfsException { AttributeValue av = AttributeValue.newAttributeValue(newValue); setAttribute("WIDTH", av); } public void setImageHeight(int newValue) throws IfsException { AttributeValue av = AttributeValue.newAttributeValue(newValue); setAttribute("HEIGHT", av); } public int getImageWidth(LibrarySession session) throws IfsException { AttributeValue av = getAttribute("WIDTH"); int width = av.getInteger(session); return width; } public int getImageHeight(LibrarySession session) throws IfsException { AttributeValue av = getAttribute("HEIGHT"); int height = av.getInteger(session); return height; } public PublicObject[] getBooks(LibrarySession session) throws IfsException { PublicObject[] relObjs = getLeftwardRelationshipObjects("BOOK_RELATIONSHIP"); return relObjs; } }
To deploy a custom bean-side Java class for a content type, follow these steps:
javac -deprecation MyCompany.MyApp.beans.Image.java
$ORACLE_HOME/9ifs/custom_classes/MyCompany/MyApp/beans/Image.class
<?xml version="1.0" standalone="yes"?> <CLASSOBJECT> <NAME>Image</NAME> <SUPERCLASS RefType = "Name">Document</SUPERCLASS> <BEANCLASSPATH>MyCompany.MyApp.beans.Image</BEANCLASSPATH> <ATTRIBUTES> <ATTRIBUTE> <NAME>Width</NAME> <DATATYPE>Integer</DATATYPE> </ATTRIBUTE> <ATTRIBUTE> <NAME>Height</NAME> <DATATYPE>Integer</DATATYPE> </ATTRIBUTE> <ATTRIBUTE> <NAME>Artists</NAME> <DATATYPE>DirectoryObject</DATATYPE> <CLASSDOMAIN RefType = "Name">DirectoryUser...</CLASSDOMAIN> </ATTRIBUTE> </ATTRIBUTES> </CLASSOBJECT>
<?xml version="1.0" standalone="yes"?> <CLASSOBJECT> <UPDATE RefType = "Name">Image</UPDATE> <BEANCLASSPATH>MyCompany.MyApp.beans.Image</BEANCLASSPATH> </CLASSOBJECT>
|
NOTE: For instructions on creating and updating ClassObjects, see Chapter 5, "Extending Content Types and Attributes". |
To test your custom Java class, follow these steps:
// Copyright (c) 2001 Oracle Corporation package MyCompany.MyApp.tests; import oracle.ifs.beans.LibraryObject; import oracle.ifs.beans.LibraryService; import oracle.ifs.beans.LibrarySession; import oracle.ifs.beans.Relationship; import oracle.ifs.beans.Selector; import oracle.ifs.common.AttributeValue; import oracle.ifs.common.CleartextCredential; import oracle.ifs.common.IfsException; import MyCompany.MyApp.beans.Image; public class TestBeanSideClass extends Object { public static void main(String[] args) { TestBeanSideClass TestBeanSideClass = new TestBeanSideClass(args); } public TestBeanSideClass(String[] args) { try { String userName = args[0]; String userPassword = args[1]; String serviceName = args[2]; String schemaPassword = args[3]; //Connect to Oracle 9iFS. LibraryService service = LibraryService.startService(serviceName, schemaPassword); CleartextCredential cred = new CleartextCredential(userName, userPassword); LibrarySession session = service.connect(cred, null); try { int i, icount, j, jcount; Image image; PublicObject[] images, books; PublicObject book; Selector s; //Obtain the Image instance s = new Selector(session); s.setSearchClassname("IMAGE"); //Execute the query and retrieve each Image. images = s.getItems(); jcount = (images == null) ? 0 : images.length; System.out.println("Images : " + jcount); for (j = 0; j < jcount; j++) { image = (Image) images[j]; System.out.println(" Image : " + image.getName()); System.out.println(" Width : " + image.getImageWidth(session)); System.out.println(" Height : " + image.getImageHeight(session)); System.out.println(" Setting Image Height and Width"); image.setImageWidth(600); image.setImageHeight(800); System.out.println(" Width : " + image.getImageWidth(session)); System.out.println(" Height : " + image.getImageHeight(session)); books = image.getBooks(session); icount = (books == null) ? 0 : books.length; System.out.println(" Books : " + icount); for (i = 0; i < icount; i++) { book = books[i]; System.out.println(" " + book.getName()); } } } catch (IfsException e) { System.out.println("An error occured."); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } //Disconnect. session.disconnect(); } catch (IfsException e) { System.out.println("Unable to connect to 9iFS."); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } catch (Exception e) { System.out.println("Unable to connect to 9iFS."); System.out.println("Ensure that you have supplied the correct"); System.out.println("connection information in the following arguments: "); System.out.println(" args[0] = User Name"); System.out.println(" args[1] = User Password"); System.out.println(" args[2] = Service Name"); System.out.println(" args[3] = Schema Password"); System.out.println("Example: "); System.out.println(" java " ); System.out.println(" MyCompany.MyApp.tests.TestBeanSideClass"); System.out.println(" system manager IfsDefault ifssys"); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } } }
javac -deprecation TestBeanSideClass.java
$ORACLE_HOME/9ifs/custom_classes/MyCompany/MyApp/tests/TestBeanSideClass.class
java MyCompany.MyApp.tests.TestBeanSideClass
The behavior of content types is implemented in server-side Java classes. The server-side classes possess the code that determines how Oracle 9iFS performs operations, such as insert, update and delete.
You can customize how Oracle 9iFS performs these operations by implementing server overrides. Overrides allow you to interrupt the standard flow of processing in the Oracle 9iFS server at certain predefined points. At these points, you can implement a custom processing task that must occur before or after an operation takes place.
For example, you may want to implement a business rule that ensures that new documents that pertain to a specific project are made accessible to members of that project. You could implement a custom processing task that checks the value of the document's Project attribute, and then automatically grants Discover access in the document's AccessControlList to a DirectoryGroup associated with that project. By implementing the task as a pre-insert override, you can ensure that the processing takes place before a document can be inserted into Oracle 9iFS.
Overrides are performed synchronously with the operation, as opposed to agents, which perform tasks asynchronously. This means that the custom processing task will be performed within the same transaction as the operation. If either fails, any changes made by the custom task and the operation will be rolled back.
The Oracle 9iFS Java API provides hooks in the server-side beans that you can use to implement custom overrides. The hooks consist of pre-operation and post-operation methods placed on the S_LibraryObject and S_Relationship class. The methods are called by Oracle 9iFS before and after performing the corresponding operation. On install, the pre-operation and post-operation methods are empty.
To customize how Oracle 9iFS performs these operations, you can create a custom server-side Java class that includes methods that override the pre-operation and post-operation methods.
The override methods can, in turn, call other custom methods in the server-side Java classes. For example, you might extend the server-side Java class to include convenience methods for getting and setting custom attributes. Or, you might include processing methods that manipulate information in the repository.
Table 17-3 lists all of the operations that have pre-operation and post-operation methods that you can override.
Overriding the pre-operation and post-operation methods (i.e., extendedPreFree()) is easier and safer than overriding the methods (i.e., Free()) that implement the Oracle 9iFS operation. To override the methods that implement Oracle 9iFS operations, you would have to reproduce Oracle 9iFS source code. The code for operations like Insert, Update, and Delete in Oracle 9iFS is both complex and risky to override in this manner. A mistake could result in database corruption. Pre-operation and post-operation methods provide a way for you to implement your custom functionality, while Oracle 9iFS handles the complexities of performing the operation and maintaining data integrity in the database. For these reasons, Oracle 9iFS only supports overriding the pre-operation and post-operation methods.
To write an override, follow these steps:
First, create a server-side Java class, S_Image, to represent your custom class in the server. S_Image extends S_TieDocument. Put this class into a new custom package, such as MyCompany.MyApp.server. (Do not add this class to the oracle.ifs.server package.)
public class S_Image extends S_TieDocument
Every server-side Java class must implement two constructors:
Table 17-4 provides a description of the constructors' parameters.
| Parameters | Datatype | Description |
|---|---|---|
|
session |
S_LibrarySession |
Current LibrarySession. |
|
data |
S_LibraryObjectData |
Data component |
|
classID |
Long |
Class ID for the object that is in the process of being created. |
public S_Image(S_LibrarySession session, S_LibraryObjectData data) throws IfsException { super(session, data); } public S_Image(S_LibrarySession session, java.lang.Long classID) throws IfsException { super(session, classID); }
Create methods that override the pre-operation and post-operation methods.
For example, you might override the extendedPreInsert() method to set a system-set attribute. System-set attributes cannot be set by a client application. Instead, the value of system-set attributes is determined by business rules that are implemented on the server.
In another case, you might overriding the extendedPreInsert() method to automatically set an attribute based on the value of another attribute. Since the attribute's value is based on another attribute value, using a ValueDefault to automatically set the attribute will not suffice. You can implement the business rule that determines the attribute's value on the server as an override.
Table 17-5 provides a description of the method's parameters.
This is an example of an extendedPreInsert() override that performs custom validation for a system-set attribute. Note that the code example includes placeholders, in bold, that must be replaced with the appropriate code for your application.
// Override Pre Insert Operation public void extendedPreInsert(OperationState opState, S_LibraryObjectDefinition def) throws IfsException { // ALWAYS call super super.extendedPreInsert(opState, def); // get our session S_LibrarySession session = getSession(); // get the approver attribute so we can check it AttributeValue av1 = def.getAttribute("APPROVER"); S_DirectoryUser approver = (av1 == null) ? null : (S_DirectoryUser) av1.getDirectoryObject(session); //validate the approver boolean verification = verifyApprover(approver); if (! verification) { // this will rollback the operation throw new IfsException( <your custom error code>, this ); } // otherwise, set the APPROVED attribute. // the APPROVED bit is not settable or updateable // by users, but the server can set it thusly AttributeValue av2 = AttributeValue.newAttributeValue(true); def.setSystemSetAttribute("APPROVED", av2); } public boolean verifyApprover(S_DirectoryUser approver) { boolean verification = false; <your validation code> return verification; } }
The first call after the method begins should be to "super." This call implements any processing that has been implemented in the same method for the superclass (e.g., S_Document). After that, implement any custom processing logic that you require.
The override methods can, in turn, call other extended methods on this or other server-side Java classes. For example, you might implement convenience methods for getting and setting custom attributes on a content type. Or, you might implement processing methods that manipulate or derive data from information in the repository.
The following sample code provides a complete, working example of a server-side override. The example extends Oracle 9iFS to automatically store .gif files as instances of a custom content type, Image. The content type possesses a server-side override that automatically sets the custom attribute, Artists, based on the value of another attribute.
<?xml version="1.0" standalone="yes"?> <CLASSOBJECT> <NAME>Image</NAME> <SUPERCLASS RefType = "Name">Document</SUPERCLASS> <ATTRIBUTES> <ATTRIBUTE> <NAME>Width</NAME> <DATATYPE>Integer</DATATYPE> </ATTRIBUTE> <ATTRIBUTE> <NAME>Height</NAME> <DATATYPE>Integer</DATATYPE> </ATTRIBUTE> <ATTRIBUTE> <NAME>Artists</NAME> <DATATYPE>DirectoryObject</DATATYPE> <CLASSDOMAIN RefType = "Name">DirectoryUser...</CLASSDOMAIN> </ATTRIBUTE> </ATTRIBUTES> </CLASSOBJECT>
<?xml version='1.0' standalone='yes'?> <OBJECTLIST> <PROPERTYBUNDLE> <UPDATE RefType='ValueDefault'>ParserLookupByFileExtension</UPDATE> <PROPERTIES> <PROPERTY Action = 'add'> <NAME> gif </NAME> <VALUE DataType = 'String'> oracle.ifs.beans.parsers.ClassSelectionParser </VALUE> </PROPERTY> </PROPERTIES> </PROPERTYBUNDLE> <PROPERTYBUNDLE> <UPDATE RefType='ValueDefault'> IFS.PARSER.ObjectTypeLookupByFileExtension </UPDATE> <PROPERTIES> <PROPERTY Action = 'add'> <NAME>gif</NAME> <VALUE DataType='String'>Image</VALUE> </PROPERTY> </PROPERTIES> </PROPERTYBUNDLE> </OBJECTLIST>
package MyCompany.MyApp.server; import oracle.ifs.common.AttributeValue; import oracle.ifs.common.IfsException; import oracle.ifs.server.S_DirectoryUser; import oracle.ifs.server.S_LibraryObjectData; import oracle.ifs.server.S_LibraryObjectDefinition; import oracle.ifs.server.S_LibrarySession; import oracle.ifs.server.OperationState; import oracle.ifs.server.S_TieDocument; public class S_Image extends S_TieDocument { // constructors public S_Image(S_LibrarySession session, S_LibraryObjectData data) throws IfsException { super(session, data); } public S_Image(S_LibrarySession session, Long classId) throws IfsException { super(session, classId); } // Overrides public void extendedPreInsert(OperationState opState, S_LibraryObjectDefinition def) throws IfsException { // Always call super super.extendedPreInsert(opState, def); // Get the LibrarySession S_LibrarySession session = getSession(); // Get the related objects S_DirectoryObject owner; AttributeValue av1, av2; av1 = def.getAttribute("OWNER"); owner = (S_DirectoryObject) av1.getDirectoryObject(session); av2 = def.getAttribute("ARTISTS"); if (av2 == null) { S_DirectoryObject[] artists = {owner}; def.setUserSetAttribute("ARTISTS", AttributeValue.newAttributeValue(artists)); } } }
To deploy your overrides for a content type, follow these steps:
|
NOTE: For instructions on creating and updating ClassObjects, see Chapter 5, "Extending Content Types and Attributes" |
javac -deprecation MyCompany.MyApp.server.S_Image.java
$ORACLE_HOME/9ifs/custom_classes/MyCompany/MyApp/server/S_Image.class
<?xml version="1.0" standalone="yes"?> <CLASSOBJECT> <UPDATE RefType = "Name">Image</UPDATE> <SERVERCLASSPATH>MyCompany.MyApp.server.S_Image</SERVERCLASSPATH> </CLASSOBJECT>
To test your server-side overrides, write a simple Java application that constructs an instance of the content type and calls the methods that have been overridden. Check the results of your operation to ensure that the pre-operation or post-operation tasks were executed.
To test the "Complete Example" that implements a server-side override for the Image content type, all you need to do is import a new .gif file into Oracle 9iFS. The .gif file extension has been registered for the Image content type so that Oracle 9iFS will automatically store the image as an instance of Image. On insert, Oracle 9iFS will automatically call the extendedPreInsert() override to implement the business rule for setting the Artists attribute.
If you want to implement custom behavior for content types that come with Oracle 9iFS out-of-the-box, and have these behaviors inherited by all descending content types, you can replace the corresponding Tie class. Tie classes are placeholders for inserting custom code at any point in the class hierarchy without directly modifying the bean-side and server-side Java classes for out-of-the-box content types.
For every class in the Oracle 9iFS Java API, there is a corresponding Tie class. Each class that descends from that class extends its Tie class, rather than the class itself. For example, the custom class Image would extend TieDocument rather than Document.
java.lang.Object +--oracle.ifs.beans.LibraryObject +--oracle.ifs.beans.TieLibraryObject +--oracle.ifs.beans.PublicObject +--oracle.ifs.beans.TiePublicObject +--oracle.ifs.beans.Document +--oracle.ifs.beans.TieDocument +--oracle.ifs.beans.Folder +--oracle.ifs.beans.TieFolder
Tie classes allow you to alter the out-of-the-box behavior of the Oracle 9iFS classes by "tie-ing" into the hierarchy at any level. Tie classes hold a place in the Oracle 9iFS hierarchy so you can customize the behavior of existing Oracle 9iFS classes and make the new behavior part of the inheritance structure. You can replace a Tie class with a custom Tie class that includes extended methods. Since Tie classes are essentially "empty," you can replace them without having to reproduce all of the code that implements the out-of-the-box functionality of the Oracle 9iFS class being extended. Since all of the descending content types extend the Tie class rather than the Oracle 9iFS class itself, they will inherit the custom methods.
For example, you may want to implement custom archiving capabilities for all public information stored in Oracle 9iFS, including documents, folders, users and groups. Since they apply to all public information, the behaviors would best be implemented on the PublicObject content type, rather than implementing the functionality multiple times by extending the Document, Folder, User, and Group content types. You could replace the TiePublicObject class with a custom TiePublicObject class that extends PublicObject and includes the methods archive() and restore(). Since Document, Folder, User, and Group classes all extend TiePublicObject, they will automatically inherit the methods on PublicObject as well as the custom methods you implemented in TiePublicObject.
To replace a bean-side Tie class, follow these steps:
First, include a class declaration. The bean-side Tie class should extend the bean-side class of the Oracle 9iFS content type that should possess the custom behavior (e.g., PublicObject). Include this class in the oracle.ifs.beans package.
public class TiePublicObject extends PublicObject
The bean-side Tie class must implement a constructor that calls the constructor for its super class. Table 17-6, "Constructor Parameters" lists the parameters for the constructor.
public TiePublicObject(LibrarySession session, Java.lang.Long id, Java.lang.Long classID, S_LibraryObjectData data, ) throws IfsException { super(session, id, classID, data); }
Once you have declared your class and included the constructor, you can add methods to implement custom behavior for all instances of the Oracle 9iFS content type and its descending content types.
public LibraryObject[] getAllRelationships(LibrarySession session, String relationshipClass) throws IfsException { Long id = getId(); LibraryObject[] relObjects, rightObjects, leftObjects; rightObjects = getRightwardRelationships(relationshipClass); leftwardObjects = getLeftwardRelationships(relationshipClass); int i; int rcount = (rightwardObjects == null) ? 0 : rightwardObjects.length; for (i = 0; i < rcount; i++) { relObjects[i] = rightwardObjects[i]; } int lcount = (leftwardObjects == null) ? 0 : leftwardObjects.length; for (i = 0; i < lcount; i++) { relObjects[rcount + i] = rightwardObjects[i]; } return relObjects; }
To replace a server-side Tie class, follow these steps:
First, declare the server-side Tie class. The server-side Tie class should extend the server-side class of the content type that should possess the custom methods (e.g., S_Relationship). Put your class into the oracle.ifs.server package.
public class S_TieRelationship extends S_Relationship
Every server-side Tie class must implement two constructors:
Table 17-7, "Constructor Parameters" provides a description of the constructors' parameters.
public S_TieFolderRelationship(S_LibrarySession session, S_LibraryObjectData data) throws IfsException { super(session, data); } public S_TieFolderRelationship(S_LibrarySession session, java.lang.Long classID) throws IfsException { super(session, classID); }
Include overrides to implement the custom behavior you want to perform on the Oracle 9iFS server. For example, you might implement an override that automatically sets an object's ACL attribute to the AccessControlList of its parent folder by overriding the extendedPreAddRelationship() method. All subclasses of the server-side Tie class will inherit these methods.
|
NOTE: See "Creating Server Overrides" for instructions on implementing overrides. |
public void extendedPostAddRelationship(S_LibraryObjectDefinition def, OperationState opState) throws IfsException { // Always call super super.extendedPostAddRelationship(opState, def); // Get the LibrarySession S_LibrarySession session = getSession(); // Get the related objects AttributeValue av1, av2; S_PublicObject f, po; av1 = def.getAttribute("LEFTOBJECT"); f = (S_PublicObject) av1.getPublicObject(session); av2 = def.getAttribute("RIGHTOBJECT"); po = (S_PublicObject) av2.getPublicObject(session); // Apply the Folder's ACL to the item being added to the folder S_AccessControlList acl = f.getAcl(); po.setAttribute("ACL", AttributeValue.newAttributeValue(acl)); }
The following examples provide a complete representation of the bean-side and server-side Tie classes for the PublicObject content type.
package oracle.ifs.beans; import oracle.ifs.beans.LibraryObject; import oracle.ifs.beans.LibrarySession; import oracle.ifs.beans.PublicObject; import oracle.ifs.beans.Selector; import oracle.ifs.common.IfsException; import oracle.ifs.server.S_LibraryObjectData; public class TiePublicObject extends PublicObject { /** * Constructs a TiePublicObject. * * @param session the session * @param id the id * @param classId the class id * @param data the data * * @exception IfsException if the operation fails * @pub */ protected TiePublicObject ( LibrarySession session, Long id, Long classId, S_LibraryObjectData data ) throws IfsException { super(session, id, classId, data); } public LibraryObject[] getAllRelationships(LibrarySession session, String relationshipClass) throws IfsException { Long id = getId(); LibraryObject[] relObjects, rightObjects, leftObjects; rightObjects = getRightwardRelationships(relationshipClass); leftwardObjects = getLeftwardRelationships(relationshipClass); int i; int rcount = (rightwardObjects == null) ? 0 : rightwardObjects.length; for (i = 0; i < rcount; i++) { relObjects[i] = rightwardObjects[i]; } int lcount = (leftwardObjects == null) ? 0 : leftwardObjects.length; for (i = 0; i < lcount; i++) { relObjects[rcount + i] = rightwardObjects[i]; } return relObjects; } }
package oracle.ifs.server; import oracle.ifs.common.IfsException; import oracle.ifs.common.AttributeValue; import oracle.ifs.server.S_AccessControlList; import oracle.ifs.server.S_PublicObject; import oracle.ifs.server.OperationState; import oracle.ifs.server.S_FolderRelationship; import oracle.ifs.server.S_LibraryObjectDefinition; public class S_TieFolderRelationship extends S_FolderRelationship { /** * Constructs a TiePublicObject. * * @param session the session * @param id the id * @param classId the class id * @param data the data * * @exception IfsException if the operation fails * @pub */ // Constructors public S_TieFolderRelationship(S_LibrarySession session, S_LibraryObjectData data) throws IfsException { super(session, data); } public S_TieFolderRelationship(S_LibrarySession session, java.lang.Long classID) throws IfsException { super(session, classID); } // Overrides public void extendedPostAddRelationship(OperationState opState, S_LibraryObjectDefinition def) throws IfsException { // Always call super super.extendedPostInsert(opState, def); // Get the LibrarySession S_LibrarySession session = getSession(); // Get the related objects AttributeValue av1, av2; S_PublicObject f, po; av1 = def.getAttribute("LEFTOBJECT"); f = (S_PublicObject) av1.getPublicObject(session); av2 = def.getAttribute("RIGHTOBJECT"); po = (S_PublicObject) av2.getPublicObject(session); // Apply the Folder's ACL to the item being added to the folder S_AccessControlList acl = f.getAcl(); po.setAttribute("ACL", AttributeValue.newAttributeValue(acl)); } }
To deploy a custom Tie class, follow these steps:
javac -deprecation TiePublicObject.java javac -deprecation S_TieFolderRelationship.java
$ORACLE_HOME/9ifs/custom_classes/tie_classes/oracle/ifs/beans $ORACLE_HOME/9ifs/custom_classes/tie_classes/oracle/ifs/server
$ORACLE_HOME/9ifs/bin/ifsstopdomain $ORACLE_HOME/9ifs/bin/ifsstartdomain
To test your custom Tie classes, follow these steps:
package MyCompany.MyApp.tests; import oracle.ifs.beans.Folder; import oracle.ifs.beans.LibraryObject; import oracle.ifs.beans.LibraryService; import oracle.ifs.beans.LibrarySession; import oracle.ifs.beans.Relationship; import oracle.ifs.beans.TiePublicObject; import oracle.ifs.common.CleartextCredential; import oracle.ifs.common.IfsException; public class TestTiePublicObject extends Object { public static void main(String[] args) { TestTiePublicObject TestTiePublicObject = new TestTiePublicObject(args); } public TestTiePublicObject(String[] args) { try { String userName = args[0]; String userPassword = args[1]; String serviceName = args[2]; String schemaPassword = args[3]; //Connect to Oracle 9iFS. LibraryService service = LibraryService.startService(serviceName, schemaPassword); CleartextCredential cred = new CleartextCredential(userName, userPassword); LibrarySession session = service.connect(cred, null); try { session.setAdministrationMode(true); Folder f = session.getPrimaryUserProfile().getHomeFolder(); System.out.println("Mome Folder : " + f.getName()); LibraryObject[] rels = f.getAllRelationships(session, "RELATIONSHIP"); int i, icount; Relationship rel; icount = (rels == null) ? 0 : rels.length; System.out.println(" Relationships : " + icount); for (i = 0; i < icount; i++) { rel = (Relationship) rels[i]; System.out.println(" " + rel.getLeftObject().getName() + " : " + rel.getRightObject().getName()); } } catch (IfsException e) { System.out.println("An error occured."); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } //Disconnect. session.disconnect(); } catch (IfsException e) { System.out.println("Unable to connect to 9iFS."); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } catch (Exception e) { System.out.println("Unable to connect to 9iFS."); System.out.println("Ensure that you have supplied the correct"); System.out.println("connection information in the following arguments: "); System.out.println(" args[0] = User Name"); System.out.println(" args[1] = User Password"); System.out.println(" args[2] = Service Name"); System.out.println(" args[3] = Schema Password"); System.out.println("Example: "); System.out.println(" java " ); System.out.println(" MyCompany.MyApp.tests.TestTiePublicObject"); System.out.println(" system manager IfsDefault ifssys"); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } } }
package MyCompany.MyApp.tests; import oracle.ifs.beans.AccessControlList; import oracle.ifs.beans.Folder; import oracle.ifs.beans.FolderDefinition; import oracle.ifs.beans.LibraryService; import oracle.ifs.beans.LibrarySession; import oracle.ifs.common.AttributeValue; import oracle.ifs.common.CleartextCredential; import oracle.ifs.common.Collection; import oracle.ifs.common.IfsException; public class TestServerTieClass extends Object { public static void main(String[] args) { TestServerTieClass TestServerTieClass = new TestServerTieClass(args); } public TestServerTieClass(String[] args) { try { String userName = args[0]; String userPassword = args[1]; String serviceName = args[2]; String schemaPassword = args[3]; //Connect to Oracle 9iFS. LibraryService service = LibraryService.startService(serviceName, schemaPassword); CleartextCredential cred = new CleartextCredential(userName, userPassword); LibrarySession session = service.connect(cred, null); try { AccessControlList defACL, propagatedACL, privateACL, publicACL; Folder propagatedF, privateF, publicF; String propagatedFName, privateFName, publicFName; // Get the session's ID to generate unique folder names. Long sessionId = session.getId(); // Create a FolderDefinition which will be used // to create three folders to test the Tie class. FolderDefinition fd = new FolderDefinition(); // Create a new folder which will be orphaned and // therefore acquire the user's default ACL. fd.setAttributeByUpperCaseName("NAME", AttributeValue.newAttributeValue("PropACLFolder" + sessionId)); propagatedF = (Folder) session.createPublicObject(fd); propagatedFName = propagatedF.getName(); System.out.println(propagatedFName + " created."); defACL = propagatedF.getAcl(); System.out.println(" The folder is currently orphaned"); System.out.println(" so it has the default ACL : " + defACL.getName()); // Get the Private and Public ACLs to be set explicitly // on two new folders. Collection systemACLs = session.getSystemAccessControlListCollection(); privateACL = (AccessControlList) systemACLs.getItems("Private"); publicACL = (AccessControlList) systemACLs.getItems("Public"); // Create another folder which has the Private ACL. fd.setAttributeByUpperCaseName("NAME", AttributeValue.newAttributeValue("PrivFolder" + sessionId)); fd.setAttributeByUpperCaseName("ACL", AttributeValue.newAttributeValue(privateACL)); privateF = (Folder) session.createPublicObject(fd); privateFName = privateF.getName(); System.out.println(privateFName + " created."); System.out.println(privateFName + "'s ACL is : " + privateF.getAcl().getName()); // Add the original folder to the Private folder to automatically // apply the Private ACL with the server override on the Tie class. privateF.addItem(propagatedF); System.out.println(" Added " + propagatedFName + " to " + privateFName); propagatedACL = propagatedF.getAcl(); System.out.println(" " + propagatedFName + "'s ACL is now : " + propagatedACL.getName()); // Create another folder which has the Public ACL. fd.setAttributeByUpperCaseName("NAME", AttributeValue.newAttributeValue("PubFolder" + sessionId)); fd.setAttributeByUpperCaseName("ACL", AttributeValue.newAttributeValue(publicACL)); publicF = (Folder) session.createPublicObject(fd); publicFName = publicF.getName(); System.out.println(publicFName + " created"); System.out.println(publicFName + "'s ACL is : " + publicF.getAcl().getName()); // Add the original folder to the Public folder to automatically // apply the Public ACL with the server override on the Tie class. publicF.addItem(propagatedF); System.out.println(" Added " + propagatedFName + " to " + publicFName); propagatedACL = propagatedF.getAcl(); System.out.println(" " + propagatedFName + "'s ACL is now : " + propagatedACL.getName()); } catch (IfsException e) { System.out.println("An error occured."); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } //Disconnect. session.disconnect(); } catch (IfsException e) { System.out.println("Unable to connect to 9iFS."); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } catch (Exception e) { System.out.println("Unable to connect to 9iFS."); System.out.println("Ensure that you have supplied the correct"); System.out.println("connection information in the following arguments: "); System.out.println(" args[0] = User Name"); System.out.println(" args[1] = User Password"); System.out.println(" args[2] = Service Name"); System.out.println(" args[3] = Schema Password"); System.out.println("Example: "); System.out.println(" java " ); System.out.println(" MyCompany.MyApp.tests.TestServerTieClass"); System.out.println(" system manager IfsDefault ifssys"); System.out.println("======================"); System.out.println(e.toString()); e.printStackTrace(); } } }
javac -deprecation TestTiePublicObject.java javac -deprecation TestServerTieClass.java
$ORACLE_HOME/9ifs/custom_classes/MyCompany/MyApp/tests/
java MyCompany.MyApp.tests.TestTiePublicObject java MyCompany.MyApp.tests.TestServerTieClass
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/customizingbehavior directory. Table 17-8 lists the sample code files and their corresponding examples.
| Example | Sample Code File |
|---|---|
|
Image.java |
|
|
Example 17-8, "Using XML to set the BeanClassPath for a New ClassObject" |
DeployBeanSideClassforNewCT.xml |
|
Example 17-9, "Using XML to Update a ClassObject's BeanClassPath" |
DeployBeanSideClassforExistingCT.xml |
|
TestBeanSideClass.java |
|
|
CreateContentType.xml |
|
|
Example 17-18, "Registering a File Extension for the Image Content Type with XML" |
RegisterContentTypeExtensions.xml |
|
Example 17-19, "Creating a Server-side Java Class for the Image Content Type" |
S_Image.java |
|
Example 17-22, "Using XML to Update a ClassObject's ServerClassPath" |
DeployServerSideClass.xml |
|
TiePublicObject.java |
|
|
S_TieFolderRelationship.java |
|
|
TestTiePublicObject.java |
|
|
TestServerTieClass.java |
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.
The following API sample code is relevant to this chapter.
| Class | Usage |
|---|---|
|
OverrideSample.java |
Demonstrates server-side overrides, extendedPreAddItem (ReportFolder) and extendedPreFree (Report). Uses a JDBC connection to update a table in a different schema |
|
|
![]() Copyright © 2001 Oracle Corporation. All Rights Reserved. |
|