| Oracle Internet File System Developer Reference Release 9.0.1.1.0 Part Number A90093-02 |
|
This chapter explains how the Oracle Internet File System implements versioning, and introduces strategies for implementing versioning in a custom application.
This chapter covers the following topics:
Versioning is the systematic retention of changes made to an object throughout its life cycle. For example, versioning allows you to track all changes made to a document's content and attributes by recording who made the change, when, and in what sequence. You can keep backups of each "version" of the document as a record of what the document looked like at a particular point in time.
Versioning also allows you to manage authoring and publishing processes by enforcing business rules for how changes can be made to an object. With the Oracle 9iFS versioning object model, you can build applications to manage a variety of processes, including serial versioning, branched versioning, and parallel versioning.
Implementing versioning functionality requires a careful balance between user requirements and system resources. Documents are the most commonly versioned objects in a content management system. Versioning documents allows you to maintain a revision history for mission-critical documentation. However, storing each version of a document will have an impact on system performance and storage space.
Oracle 9iFS provides a flexible versioning model capable of supporting a wide variety of processes for authoring and publishing information. Most PublicObjects can be versioned. PublicObjects are objects that Oracle 9iFS users can access, such as documents and folders. These objects descend from PublicObject in the Oracle 9iFS class hierarchy. By default, only the Document class is set to be versionable. If you plan to version other classes of objects, take into account the disk space and performance cost involved. For the purpose of illustration, this chapter focuses on how documents are versioned.
A nonversioned document in the repository is represented as an instance of the Document class, or a custom class that extends Document. The instance possesses structured information describing the document, such as Name, Owner, and CreationDate. These are represented as attributes on the Document class. Documents also possess unstructured content represented as an instance of ContentObject referenced by the ContentObject attribute on the Document class.
When a document is versioned, Oracle 9iFS creates three additional types of objects to manage all of the versions created during the document's life cycle: a Family, VersionSeries, and VersionDescription, illustrated in Figure 14-1.
Out-of-the-box, Oracle 9iFS clients and protocols implement a serial versioning model. In this versioning model, a document's Family includes one VersionSeries that contains all of the document's versions. Each version must, therefore, be made sequentially, one after another.
This versioning model also makes it possible to build custom applications with more complex versioning paradigms, such as parallel or branched versioning, shown in Figure 14-2. A Family can contain multiple VersionSeries to represent separate sequences of changes that may have been made in parallel, and which may branch from and merge into one another.
Different VersionDescriptions in a VersionSeries can reference different classes of objects, therefore representing changes in the state of a document from one class to another. For example, the first version of a document may have been a RequirementsDocument (subclass of Document), which was changed into a DesignSpecification in the second version.
VersionDescriptions can also reference the same instance of Document. For example, a document may have a Work-In-Progress VersionSeries and a Published VersionSeries. The third version of the Work-In-Progress VersionSeries may represent the first version in the Published VersionSeries. In this case, the VersionDescriptions representing the third Work-In-Progress version and first Published version can reference the same instance of Document.
Oracle 9iFS provides a Java API with which you can build custom applications that implement versioning functionality. Table 14-1, "Document Attributes and Methods", Table 14-2, "Family Attributes and Methods", Table 14-3, "VersionSeries Attributes and Methods", and Table 14-4, "VersionDescription Attributes and Methods" list the key attributes and methods of each of the versioning classes in the Oracle 9iFS Java API. For a complete description of these classes, please refer to the Javadoc.
Ultimately, all versions of a document are stored as instances of the Document class. When users modify a document, an application can enable the following actions:
The Document class has a set of key attributes to keep track of changes made to the document. Most of these attributes and methods, shown in Table 14-1, "Document Attributes and Methods", are inherited from the superclass PublicObject, and can be used to version other types of objects. In addition, the Document class provides attributes and methods for working with a document's content.
When a user makes changes to a document, the application can allow the user to replace the attribute values or content of the document without creating a new version of the document. To support this feature, the PublicObject possesses attributes to track the date and user who originally created and last modified the document. The PublicObject class also possesses a Family attribute, which makes it easy to locate the Family of a versioned document.
When a document is versioned, Oracle 9iFS creates an instance of the Family class to manage all of the versions created for the document during its life cycle. A versioned document can belong to only one Family. The attributes and methods important for managing a family are shown in Table 14-2, "Family Attributes and Methods".
"Resolving Versioned Documents" describes in detail how getResolvedPublicObject(), DefaultVersionDescription, and PrimaryVersionSeries are used to resolve the current state of a versioned document.
A VersionSeries represents a series of sequential changes (versions) made to a document. The attributes and methods for managing these changes are shown in Table 14-3, "VersionSeries Attributes and Methods".
"Making a Document Versioned" describes in detail how these methods and attributes can be used to version a document.
A VersionDescription describes a version of a document within the context of a version series. The attributes and methods for working with a specific version of a document are shown in Table 14-4, "VersionDescription Attributes and Methods".
You can use the Oracle 9iFS versioning classes to provide versioning functionality in a custom application. For example, versioning applications can create a new version in three steps:
To implement this functionality, the versioning application uses the following API calls:
reserveNext() method on the document's VersionSeries object to prevent other users from making changes at the same time. The application sets the Reservor, ReservationDate, ReservationComments, and WorkPath attributes on the VersionSeries to provide users with information about who, why, and when it was reserved.
setContent() method on the Document instance to store the user's iterations temporarily before creating the new version of the document.
newVersion() method to create a new VersionDescription and set the values for the new version's VersionLabel, RevisionComments, and PublicObject. It sets the PublicObject attribute on the new VersionDescription to reference the Document instance that was used to store the user's changes as the VersionSeries PendingPublicObject.
This section demonstrates how to use the Oracle 9iFS Java API to build a custom application with serial versioning functionality for documents by performing the following basic versioning tasks:
By default, when a document is first created in Oracle 9iFS, it is not versioned. To allow users to version the document, your application must first create the infrastructure objects for a versioned document: Family, VersionSeries, and VersionDescription.
To make a document versioned, follow these steps:
You don't have to explictly create definitions for all four components of a versioned document (e.g., DocumentDefinition, VersionDescriptionDefinition, VersionSeriesDefintion, FamilyDefinition). Alternatively, you can use a VersionDescriptionDefinition which references the Document to be versioned. When the VersionDescriptionDefinition is passed to the LibrarySession, Oracle 9iFS will automatically create all four components of the versioned document. From these two definition objects, Oracle 9iFS can create the other components. Example 14-1 illustrates how to make a document versioned by explicitly defining all components. Example 14-2 illustrates how to uses a VersionDescriptionDefinition to implicitly create the components of a versioned document.
You can use the SecuringPublicObject attribute to control access to all components of a versioned document in one place. You can apply one component's AccessControlList to all components of the versioned document by referencing that component in the other components' SecuringPublicObject attribute. When the SecuringPublicObject attribute is set, Oracle 9iFS will automatically use the referenced object's AccessControlList to control access to the referencing object. When you make an existing document versioned, Oracle 9iFS will automatically set the SecuringPublicObject attribute on the Document, VersionDescription, and VersionSeries to reference the document's Family. When you create a new versioned document, you must explicitly set the SecuringPublicObject attribute, as illustrated in Example 14-2.
|
NOTE: To learn more about using the SecuringPublicObject attribute, see Chapter 15, "Security". |
Document doc = ...
FamilyDefinition fd = new FamilyDefinition ( session ); fd.setAttribute( PublicObject.NAME_ATTRIBUTE , AttributeValue.newAttributeValue ( po.getName() ) ); AccessControlList acl = doc.getAcl(); fd.setAttribute(PublicObject.ACL_ATTRIBUTE, AttributeValue.newAttributeValue(acl));
VersionSeriesDefinition vsd = new VersionSeriesDefinition(session); vsd.setFamilyDefinition(fd);
VersionDescriptionDefinition vdd = new VersionDescriptionDefinition(session); vdd.setPublicObject(doc); vdd.setVersionSeriesDefinition(vsd); vdd.setOwnerBasedOnPublicObjectOption ( true );
VersionDescription vd = (VersionDescription) session.createPublicObject(vdd);
VersionSeries vs = vd.getVersionSeries(); Family family = vs.getFamily();
DocumentDefinition dd = new DocumentDefinition(session); dd.setAttribute(Document.NAME_ATTRIBUTE, AttributeValue.newAttributeValue(docname)); Collection formatColl = session.getFormatCollection(); Format fmt = (Format) formatColl.getItems("Text"); dd.setFormat(fmt); dd.setContent("A new versioned document."); Folder hf = session.getUser().getPrimaryUserProfile().getHomeFolder(); dd.setAddToFolderOption(hf);
VersionDescriptionDefinition vdd = new VersionDescriptionDefinition(session); vdd.setAttribute(VersionDescription.NAME_ATTRIBUTE, AttributeValue.newAttributeValue("Versioning1 VersionDescription")); vdd.setAttribute("VERSIONLABEL", AttributeValue.newAttributeValue("Version 1.0")); vdd.setPublicObjectDefinition(dd);
VersionDescription vd = (VersionDescription)session.createPublicObject(vdd);
Family f = vd.getFamily(); VersionSeries vs = vd.getVersionSeries(); Document d = (Document) vd.getResolvedPublicObject();
d.setSecuringPublicObject(f); vd.setSecuringPublicObject(f); vs.setSecuringPublicObject(f);
After making a document versioned, you can allow end users to check out the document. When a user checks out a document, other users cannot create new versions of the document.
To check out a document, follow these steps:
Document doc ...
if (doc.isVersioned()) {
Family family = doc.getFamily(); VersionSeries vs = family.getPrimaryVersionSeries();
if (!vs.isReserved() && !family.isLocked()) {
vs.reserveNext(null, "File Reserved By " + session.getDirectoryUser().getDistinguishedName()); } }
When reserveNext() method is called to check out a document, the method also creates a new Document instance based on the last version of the document, and then sets the VersionSeries' PendingPublicObject attribute to that Document instance. The PendingPublicObject serves as a temporary holding place for all changes made to the document while it is checked out. Each iteration of the document is recorded in Oracle 9iFS as a Document instance and referenced by the PendingPublicObject attribute on the VersionSeries.
To hold pending changes your application can fetch and update the document referenced by the PendingPublicObject attribute with the following steps:
Document doc .....
if (doc.isVersioned()) { Family.family = doc.getFamily(); VersionSeries vs = family.getPrimaryVersionSeries();
if (vs.isReservedByCurrentUser() ) { PublicObject ppo = vs.getPendingPublicObject();
DocumentDefinition dd = (DocumentDefinition) ppo.getDefinition(); dd.setContent("Changed content.");
ppo.update(dd); } }
When the author is finished making changes to the document, the changes can be checked in as a new version of the document. To check in the new document version, follow these steps:
Document doc .....
if (doc.isVersioned()) { Family family = doc.getFamily(); VersionSeries vs = family.getPrimaryVersionSeries();
if (vs.isReservedByCurrentUser() ) { PublicObject ppo = vs.getPendingPublicObject();
if (ppo != null) { vdd = new VersionDescriptionDefinition( session ); vdd.setAttribute(vd.REVISIONCOMMENT_ATTRIBUTE, AttributeValue.newAttributeValue( "Updated document to incorporate review comments."));
vd = vs.newVersion(vdd); } } }
At any time while the document is checked out, the user can cancel the check out. Cancelling a check out will discard the changes held temporarily in the PendingPublicObject and release the VersionSeries so that other users can check out the document.
To cancel a check out on a document, follow these steps:
Document doc .....
if (doc.isVersioned()) { Family family = doc.getFamily(); VersionSeries vs = family.getPrimaryVersionSeries();
if (vs.isReservedByCurrentUser() ) {
vs.unReserve(); } }
After a document has been versioned, you can obtain a history of all changes made to the document, and access all retained document versions. To view the document's history, follow these steps:
Document doc .....
if (doc.isVersioned()) { Family family = doc.getFamily(); VersionSeries vs = family.getPrimaryVersionSeries();
VersionDescription[] versions = vs.getVersionDescriptions(); Document docVersion; Date lastModifyDate; Long size; PublicObject version; String docVersionName, format, lastModifier, revisionComment; VersionDescription vd; for (int i = 0; i < versions.length; i++) { vd = versions[i]; version = vd.getPublicObject(); versionName = version.getName(); lastModifier = version.getLastModifier().getName(); lastModifyDate = version.getLastModifyDate(); revisionComment = vd.getRevisionComment();s if (docVersion instanceof Document) { docVersion = (Document) version; format = docVersion.getFormat().getName(); size = docVersion.getContentSize(); } } }
Since each version created is retained in the repository, versioning documents will have an impact on the storage space and performance of the system. You can allow end users to keep the repository lean by deleting unnecessary versions.
To delete a document version, follow these steps:
VersionDescription vd .....
if (!vd.isLatestVersionDescription()) {
vd.free(); }
Deleting a versioned document is as easy as deleting a non-versioned document. When the free() method is called on a document's Family, Oracle 9iFS automatically deletes its versioning components, including the VersionSeries, VersionDescriptions, and all instances of Document that represent a version of the document.
Document doc ..... Family family = doc.getFamily();
if (!family.isLocked()) {
family.free(); }
Folders provide a way to organize and browse through the repository to access documents. When a nonversioned document is foldered, the folder directly references the document; that is, the instance of the Document class. However, when a document is versioned, the folder can reference any component of the versioned document: its Family, a VersionSeries, or a VersionDescription. This is useful for providing users with an easy way to access specific points in the document's life cycle for different purposes.
For example, a Release 1.0 Documentation Set folder was created to contain the documentation released with Oracle 9iFS 1.0. The folder references the specific version, Version 3, of the documentation delivered with that release. This is accomplished by foldering the VersionDescription that represents Version 3.
VersionDescription vd = ...
Folder f = .....
f.addItem(vd);
A Future Documentation folder may be created to contain the documentation set being developed for the next release of Oracle 9iFS. In this case, the folder references the Work-in-Progress VersionSeries. An author can access the document from here to obtain the latest version of the Work-in-Progress VersionSeries.
Folder f = ....
Document doc = .... Family family = doc.getFamily(); VersionSeries[] vss = family.getVersionSeries(); int i; String vsName; VersionSeries vs; for (i = 0; i < vss.length; i++) { vs = vss[i]; vsName = vs.getName(); if (vsName equals ("Work-in-Progress")) {
f.addItem(vs); break; } }
A Current Documentation folder may be created to make it easy for users to access the most recently published version of the documentation. This is accomplished by foldering the document's Family. General consumers can access the document version that are designated as the default version for the document's primary version series, the Published VersionSeries.
Folder f = ....
Document doc = .... Family family = doc.getFamily();
f.addItem(f);
When you make a document versioned, you can update all folders containing the document to reference the document's Family. By referencing the document's family, you will be assured that end users will retrieve the most current version of the document, rather than the first version of the document.
Document doc = .... Make a document versioned. FamilyDefinition fd = new FamilyDefinition ( session ); fd.setAttribute( PublicObject.NAME_ATTRIBUTE , AttributeValue.newAttributeValue ( po.getName() ) ); AccessControlList acl = doc.getAcl(); fd.setAttribute(PublicObject.ACL_ATTRIBUTE, AttributeValue.newAttributeValue(acl)); VersionSeriesDefinition vsd = new VersionSeriesDefinition(session); vsd.setFamilyDefinition(fd); VersionDescriptionDefinition vdd = new VersionDescriptionDefinition(session); vdd.setPublicObject(doc); vdd.setVersionSeriesDefinition(vsd); vdd.setOwnerBasedOnPublicObjectOption ( true );
Transaction transaction = session.beginTransaction();
try { VersionDescription vd = (VersionDescription) session.createPublicObject(vdd);
VersionSeries vs = vd.getVersionSeries(); Family family = vs.getFamily();
Folder fldr; Folder[] fldrs = doc.getFolderReferences();
for(i=0; i < fldrs.length; i++) { fldr = fldrs[i]; fldr.removeItem(doc); fldr.addItem(family); } session.completeTransaction(transaction); } catch (IfsException e) { session.abortTransaction(transaction); throw e; }
Notes:
- "Resolving Versioned Documents" describes how Oracle 9iFS resolves which version of a document should be returned when accessed from VersionDescription, VersionSeries, or Family.
- Example 14-13 uses a transaction to ensure that all folders are updated when the document is versioned. See Chapter 16, "Managing Sessions and Transactions" for instructions on how to use the transaction management capabilities of Oracle 9iFS.
When a user tries to view a versioned document, which of its versions should represent its current state? The Oracle 9iFS versioning model makes it possible to control how a document's current state is resolved. Furthermore, an application can configure a versioned document so that the document's state is resolved differently depending on which node in the versioning model is being accessed.
In the example illustrated by Figure 14-4, "Branched Versioning Model", an application can provide access to the officially released version of a Product Plan document in the Publications folder by foldering its Family object. When a user tries to view the content for the Product Plan via the Family object, Oracle 9iFS automatically returns the content of the last version of the Family's PrimaryVersionSeries, Published Series.
Oracle 9iFS provides a method, getResolvedPublicObject(), to automatically resolve which document represents the current state of a specific version (the VersionDescription), a particular series of versions (the VersionSeries), or the 'living document' (the Family). Certain attributes on the Family and VersionSeries can be used by an application to control how the document's state is resolved.
The getResolvedPublicObject() method employs the following logic when being used to resolve each component of a versioned document.
In the example illustrated by Figure 14-4, "Branched Versioning Model", Version 2 of the Published Series resolves to the Design Spec referenced by its PublicObject attribute.
In the example illustrated by Figure 14-4, "Branched Versioning Model", the resolved PublicObject for the Internal Series VersionSeries is the Design Spec referenced by Version 3. However, if the Internal Series DefaultVersionDescription is set to Version 1, Oracle 9iFS returns the Requirements Spec.
In the example illustrated by Figure 14-4, "Branched Versioning Model", if Published Series were the PrimaryVersionSeries for Product Plan, then Oracle 9iFS returns the Design Spec referenced by Version 2. However, if the DefaultVersionDescription on the Product Plan was set to Version 3 of the Internal Series, Oracle 9iFS returns the Design Spec referenced by Version 3.
Example 14-14 demonstrates how to use the getResolvedPublicObject() method on each component of a versioned document.
Document doc = ....
PublicObject rpo = doc.getResolvedPublicObject();
Family family = doc.getFamily(); PublicObject rpo = family.getResolvedPublicObject();
VersionSeries vs = doc.getVersionSeries(); PublicObject rpo = vs.getResolvedPublicObject();
VersionDescription vd = vs.getLastVersionDescription(); PublicObject rpo = vd.getResolvedPublicObject();
Oracle 9iFS is installed with sample code that helps you get started working with the Java API. The API sample code is located in the <ORACLE_HOME>/9ifs/samplecode/oracle/ifs/examples/devdoc/api directory.
Table 14-5 lists the API sample code that is relevant to this chapter.
| Class | Usage |
|---|---|
|
VersioningSample.java |
Versions a document. |
|
|
![]() Copyright © 2001 Oracle Corporation. All Rights Reserved. |
|