Managing custom fields using the REST document service in IBM Lotus Quickr 8.1.1 services for WebSphere Portal

This article introduces the Representational State Transfer (REST) document service's custom field support in IBM® Lotus® Quickr™ 8.1.1 services for IBM WebSphere® Portal, also called the Java™ 2 Platform, Enterprise Edition (J2EE) version of Lotus Quickr. We explain the concept of custom fields, discuss the programming model to manage custom fields with the Lotus Quickr REST document service, and demonstrate a business scenario for extending the core set of document attributes.

Share:

Xiao Pei Liu (liuxpei@cn.ibm.com), Software Engineer, IBM

Xiao Pei Liu is a Software Engineer working on API Testing for the IBM Lotus Quickr team in Beijing, China. You can reach her at liuxpei@cn.ibm.com.



Bing Feng Han, Software Engineer, IBM

Bing Feng Han is a Software Engineer working with the Lotus Quickr Connector team at IBM's Beijing, China facility. You can reach Bing Feng at bfhan@cn.ibm.com.



Zhang Zi Xuan, Software Engineer, IBM

Zhang Zi Xuan is a Software Engineer working with the Lotus Quickr Service team in Beijing, China. You can reach Zi Xuan at zhangzix@cn.ibm.com.



Derek Carr, Advisory Software Engineer, IBM

Derek Carr is an Advisory Software Engineer at IBM working with the Lotus Quickr team in Research Triangle Park, NC. You can reach Derek at dwcarr@us.ibm.com.



23 February 2010

Also available in Chinese Japanese Portuguese

Editor's note: Know a lot about this topic? Want to share your expertise? Participate in the IBM Lotus software wiki program today.

Prerequisites

This document should be especially helpful to users who are looking to migrate or integrate content from existing content repositories that support custom attributes. To get the most from this article, you should have an understanding of:

  • Lotus Quickr services for WebSphere Portal
  • REST services
  • Atom Syndication Format and Atom Publishing Protocol (AtomPub)
  • Java programming
  • Apache Abdera, which is a Java implementation of Atom and AtomPub protocols

Overview of custom fields support in Lotus Quickr 8.1.1

Lotus Quickr is team collaboration software that helps you share content, collaborate, and work faster online with your teams. The document library component of Lotus Quickr allows you to manage all your team files in a collaboration environment with enhanced abilities, including versioning support, work flow management, and the ability to add custom fields to a document.

Custom fields

In general, metadata is needed to describe the primary document content. Each document in Lotus Quickr has a standard set of metadata fields. The common set of metadata includes file name, author, created time, and updated time; however, in some cases, the common metadata is not sufficient to describe the file properties.

As a result, custom fields were introduced, which are a set of extended properties that users can define and provide for a specific type of document. These custom fields are also quite helpful in searching for content in Lotus Quickr, in which custom fields are defined by a property sheet and associated with documents by document type.

Property sheet

A property sheet contains several fields that are designed by users to meet a specific business need. The field types, options, default values, field orders, and so on are defined by the user to attach a custom form of data elements to the document.

Property sheets are usually defined and used locally within a document library, but a Lotus Quickr administrator can define shared property sheets that can be used in any of the document libraries on the Lotus Quickr server.

To create a property sheet, go to your place main page in the Web user interface (UI), expand Manage Document Elements, select Property Sheets, and then click Create Property Sheet (see figure 1).

Figure 1. Create Property Sheet on Web UI
Create Property Sheet on Web UI

To add fields to the property sheet, click Add Fields on the right side of the Create Property Sheet window, and enter the field name, option values, display style, default values, and so on (see figure 2).

Figure 2. Add fields to the property sheet
Add fields to the property sheet

Document type

Property sheets provide reusable sets of field definitions. Multiple property sheets can be attached to a document, and the set of available property sheets for any document is defined by the document's associated document type.

A document type provides a mechanism by which the behaviors of a document can be defined, including document templates, versioning, workflow definition, and custom fields. When the document of a particular type is uploaded, all these predefined parameters come into effect.

As described above, the custom fields are not defined in the document type directly; instead, they are defined in a property sheet and then added to the document type. Similar to property sheets, document types are usually defined in the document library scope, but they can be defined for all document libraries by the Lotus Quickr administrator.

To manage all your document types, go to your place main page on the Web UI, expand Manage Document Elements, and select Document Types. While creating or updating a document type, you can select property sheets to be added or removed from the document type.

To add a property sheet while creating a document type, click the Add an existing property sheet link in the Property Sheets section, and in the Choose Property Sheet window, select the property sheet that you want to add (here, New Property Sheet; see figure 3).

Figure 3. Add property sheet to created document type
Add property sheet to newly created document type

Apply custom fields to a document

After you have property sheets and document types created in your place, you can upload or create documents and select your expected document type. You must then input the properties that were defined in the property sheet; the values that you input become the document’s metadata.

To choose a document type and input the fields defined by your property sheet, follow these steps:

  1. Select Upload on the place main page, and, in the Upload Files window, click the Change link in the Document type section (see figure 4).
  2. Select the document type that you want to use in the Choose Document Type window (here, New Document Type).

Notice that the properties in the document type are now shown in a new Document type properties section at the bottom of the page.

Figure 4. Choose document type and fields in property sheet
Choose document type and fields in property sheet

Custom field support in Lotus Quickr public services

Lotus Quickr also includes a set of public services (APIs) to access content managed by Lotus Quickr. Using these services, you can build customized applications or integrate Lotus Quickr contents with other applications.

The REST document service is a primary part of the Lotus Quickr public services, allowing you to programmatically access and update much of the information in Lotus Quickr document libraries using a RESTful programming model that follows the Atom Publishing Protocol (RFC 5023) and implements the Atom Syndication Format (RFC 4287).

Beginning in Lotus Quickr 8.0, the REST document service provides the abilities to create, retrieve, update, and delete documents in Lotus Quickr document libraries, but customized fields were not supported until Lotus Quickr 8.1.1, released in December 2008.

In the following sections of this article, we introduce the programming model of managing custom fields in the REST document service and demonstrate how to use the services in real applications, using a program example.


Managing custom fields using the REST programming model

NOTE: In the previous section of this article, we used the term “property sheet” to describe both the custom field definitions and the custom fields implemented in a document. In the REST programming model, however, the term “property sheet type” is used to describe the definition of custom fields. After a property sheet type is implemented by a document, the custom fields' values of the property sheet type are called a “property sheet.” In the remainder of this article, we use the new terms in the REST programming model.

Creating a property sheet type

To create a property sheet type in a library, you can send a POST request to the property sheet type's feed URL, http://<host>:<port>/dm/atom/library/<libraryId>/propertysheettypes/feed, by supplying a property-sheet-type Atom entry in the body of a HTTP request (see listing 1).

Listing 1. Request to create a property sheet type
POST /library/08ca5f0044ab2d6a858eed71ca20d4cf/propertysheettypes/feed HTTP/1.1
Host: example.com
Content-Type: application/atom+xml
Content-Length: nnnn
Authorization: Basic ...

<entry xml:lang="en" xmlns:td="urn:ibm.com/td">
    <id>urn:lsid:ibm.com:td:8b40f50049641d8789a2d97accc4bd33</id>
    <td:uuid>8b40f50049641d8789a2d97accc4bd33/<td:uuid>
    <category term="propertysheettype" scheme="tag:ibm.com,2006:td/type" 
    label="propertySheetType"></category>
    <author>
      <uri>uid%3Dquikradm%2Co%3Ddefault+organization</uri>
      <name>quikradm</name>
      <email></email>
    </author>
    <title type="text">example</title>
    <updated>2008-04-23T00:40:42.141Z</updated>
    <summary type="text">example Property Sheet Type</summary>
<content type="application/atom+xml" 
src="library/108c368048681104a123e3be2a21d9f5/propertysheettype">
  <meta:propertySheetTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:clb="http://content.ibm.com/clb/1.0" 
  xmlns:meta="http://metadata.model.xsd.clb.content.ibm.com/1.0">
  <meta:property xsi:type="meta:ClbPropertyType" dataType="string" 
  maxLength="2048" multiple="false" propertyId="clb:ps1" 
  propertyName="clb:p_a6aa8d78-bc9e-4a35-a243-000aaaa8af12" 
  readonly="false" required="false" searchable="true">
    <meta:label label="Name" lang="en" />
    <meta:style name="ibm:textVariant" value="medium" />
  </meta:property>    <meta:property xsi:type="meta:ClbPropertyType" 
  dataType="boolean" multiple="false" propertyId="clb:ps2" 
  propertyName="clb:p_f4179b4b-9c29-45ea-a18b-3e507002015d" 
  readonly="false" required="false" searchable="true">
    <meta:label label="Gender" lang="en" />
  </meta:property>
</meta:propertySheetTemplate>
</content>

    <td:contrainedMimeType>application/atom+xml<td:contrainedMimeType>
    <td:isExtracted>true<td:isExtracted>
</entry>

The above Atom entry contains a <content> element that stores the property-sheet template XML definition that enables custom fields to be defined.

The <propertySheetTemplate> element can contain zero or more <property> elements that define an individual piece of custom fields in the system.

Each element must contain a propertyId attribute that defines a unique property identifier within a single <propertySheetTemplate>.

In addition, there are several other supported attributes. Table 1 lists all the attributes supported for the <property> element.

Table 1. Attributes supported in the <property> element
AttributeDescription
datatypeThis required attribute contains a string from an enumerated set of options that specifies the primitive data type for a metadata property. The primitive data type determines which dynamic map available on a ClbPropertySheet holds this metadata value. The following primitive data type values are supported:
  • String
  • Double
  • Long
  • dateTime
  • Boolean

By default, if no value is specified in the PropertySheetType XML template, the data type is equal to string.
multipleThis optional attribute contains a Boolean value to determine if the property supports multiple values. The default value is false.
indexableThis optional attribute contains a Boolean value to determine if this property should be added to an index. The default value is false.
propertyIdThis required string attribute contains an identifier for an individual property within a property sheet template.
propertyNameThis required string attribute contains a qualified name for the property in the back-end repository. This name must be defined in the clb: prefix and must be unique within a repository. It is the key in the dynamic map for the data type that contains this property value.
readonlyThis optional attribute contains a Boolean value that specifies if this property is a read-only value in the content repository. The default value is false.
requiredThis optional attribute contains a Boolean value that specifies if this property is a required value in the content repository. The default value is false.
searchableThis optional attribute contains a Boolean value that specifies if this property supports text search. The default value is true.
maxLengthThis optional attribute specifies the maximum length constraint for string properties. If not specified, the default maximum length is set to 252 characters.

Besides the attributes, each <property> element can contain the following:

  • Some optional subelements, including a set of <label> elements each mapped to a locale
  • A set of <style> elements providing a hint for the visual representation of the property
  • A list of <option> elements defining a set of possible values for the property
  • A list of <defaultValue> elements defining the default value to be applied to the property by consuming applications, if none is specified

An example property element is shown in listing 2.

Listing 2. <property> element code example
<property
  propertyId="prop1"
  dataType="string"
  multiple="false"
  propertyName="clb:p1234"
  readonly="false"
  required="true"
  searchable="false">
<label label="Gender" lang="en" />
  <style name="ibm:selectionType" value="radio" />
  <defaultValue>Female</meta:defaultValue>
  <option>
      <value>Female</meta:value>
      <label label="Female" lang="en" />
  </option>
  <option>
      <value>Male</meta:value>
      <label label="Male" lang="en" />
  </option>
 </property>

In addition to creating a property sheet type, you can get a list of property sheet types by sending a GET request to the property sheet types URL. Also, you can get, update, or delete a specific property sheet type by sending a GET, PUT, or DELETE operation to the property-sheet-type entry URL as follows:

http://<host>:<port>/dm/atom/library/<libraryId>
/propertysheettypes/< propertysheettype-id>/entry

For more details about the property-sheet-type operations in the Lotus Quickr REST Document Service, see the Documents Services topic in the Lotus Quickr wiki.

Creating a document type

To create a document type in a library, you can send a POST request to the document type's Feed URL

http://<host>:<port>/dm/atom/library/<libraryId>/documenttypes/feed by supplying a document type Atom entry in the body of an HTTP request (see listing 3).

Listing 3. Request to create a document type
POST /library/08ca5f0044ab2d6a858eed71ca20d4cf/documenttypes/feed HTTP/1.1
Host: example.com
Content-Type: application/atom+xml
Content-Length: nnnn
Authorization: Basic ...

<entry xml:base="http://example.com/dm/atom/library/
08ca5f0044ab2d6a858eed71ca20d4cf/" xmlns="http://www.w3.org/2005/Atom">
    <id>urn:lsid:ibm.com:td:4e05cb0044f7e4f1937e932188721110</id>
    <td:uuid>4e05cb0044f7e4f1937e932188721110/<td:uuid>
    <category term="documenttype" scheme="tag:ibm.com,2006:td/type" 
    label="documentType"></category>
    <author>
      <uri>uid%3Dquikradm%2Co%3Ddefault+organization</uri>
      <name>quikradm</name>
      <email></email>
    </author>
    <title type="text">word doc</title>
    <updated>2008-04-23T00:40:42.141Z</updated>
    <summary type="text">word Document Type</summary>
    <content type="application/atom+xml" 
    src="library/08ca5f0044ab2d6a858eed71ca20d4cf/documenttype"></content>
    <td:defaultExtension>doc<td:defaultExtension>
    <td:template>209c511448682203a123e3bd1a328f82<td:template>
    <td:propertysheettype>103f553208383112a333b3bd1a319d81
    <td:propertysheettype>    
    <td:propertysheettype>201d33530848122a333b4cd2a419c914
    <td:propertysheettype>    <td:propertysheettype>
    1029c238299d122c332d99f1c491d882<td:propertysheettype>
    <td:versioning>none<td:versioning>
    <td:approvalEnabled>true<td:approvalEnabled>
    <td:approvalType>serial<td:approvalType>    
    <td:approvers>uid%3Dquikradm%2Co%3Ddefault+organization
    <td:approvers>
    <td:expandGroupApprovers>false<td:expandGroupApprovers>
</entry>

The <td:propertysheettype> element in the entry contains the Universally Unique Identifier (UUID) of the property sheet type to be used for this document type.

In addition to creating a document type, you can get a list of document types by sending a GET request to the document types' Feed URL. Also, you can get, update, or delete a specific document type by sending a GET, PUT, or DELETE operation to the document-type entry URL as follows:

http://<host>:<port>/dm/atom/library/<libraryId>
/documenttypes/< documenttype-id>/entry

For more details about the document type operations in the Lotus Quickr REST document service, see the Documents Services topic in the Lotus Quickr wiki.

Creating and updating documents with property sheets

After the document type is created, you can provide the values for the custom fields while uploading the document of a specific document type. Also, you can send a POST request to the Library Feed URL

http://<host>:<port>/dm/atom/library/<libraryId>/feed?doctype=
<documentTypeId>&includePropertySheets=true
or the Folder Feed URL

http://<host>:<port>/dm/atom/library/<libraryId>/folder/
<folderId>feed?doctype=<documentTypeId>&includePropertySheets=true
by supplying a document Atom entry with custom field values in the body of the request. The custom field values are described by the <snx:field> element contained in the document Atom entry, and they take effect only if the URL parameter includePropertySheets is set to true.

The value of the URL parameter doctype is specified as the document type of the document. The attributes of the <snx:field> element are described in table 2.

Table 2. Attributes for <snx:field> XML element
AttributeIs required?Description
fidYesDefines the propertyName in the clb namespace for this resource property.
nameYesThe title of the propertysheettype for this resource property.
pstIdYesUUID of the propertysheettype for this resource property.
typeYesDefines the field type. The following values are supported:
  • date
  • string
  • double
  • boolean
  • long

The example code in listing 4 shows the HTTP request to create a document with custom fields. Note that the request body is an Atom entry that represents a document and includes several <snx:field> elements.

Listing 4. Request to create a document with custom field values
POST /library/bd03fd75-99c2-46bb-b438-2d151faa7348/
feed?doctype= 4e05cb0044f7e4f1937e932188721110
 &includePropertySheets=true HTTP/1.1
Host: example.com:9080
Content-Type: application/atom+xml; charset="utf-8"
User-Agent: Thingio/1.0

<entry xmlns="http://www.w3.org/2005/Atom">
	<category term="document" scheme="tag:ibm.com,2006:td/type" 
	label="document"></category>
	<summary type="text">Test posting an ATOM document with 
	metadata values</content>
	<title type="text">testPostAtomDocument.txt</title>
	<author>
		<name>mshani</name>
	</author>
<snx:field
  name="pst1"
  fid="clb:ps0"
  pstId="CF2432219C73BB73162A79E0A995292402C7"
  type="date" >
   2008-06-12T04:00:00Z
 </snx:field>
 <snx:field
  name="pst2"
  fid="clb:ps1"
  pstId="F23432219C73BB73162A79E0A9952922520F"
  type="string" >
    string example text
 </snx:field>
 <snx:field
  name="pst3"
  fid="clb:ps2"
  pstId="DD2232219C73BB73162A79E0A99529242C77"
  type="long" >
   2302
 </snx:field>
 <snx:field
  name="pst4"
  fid="clb:ps3"
  pstId="DD2112219C73BB73162A79E0A995292513C8"
  type="double" >
   123.12345
 </snx:field>
 <snx:field
  name="pst5"
  fid="clb:ps4"
  pstId="DD1232219C73BB73162A79E0A99529251D78"
  type="boolean" >
   true
 </snx:field>
</entry>

You can also get or update the document custom field values by sending a GET or PUT operation to the document entry URL as follows:

http://<host>:<port>/dm/atom/library/<libraryId>/document/< document-id>/entry?includePropertySheets=true

In this section, we covered the REST programming model for custom fields, which includes operations of property sheet types and document types, and creating documents with <snx:field> elements that represent custom fields values in the Atom Entry. Next, we show some codes manipulating custom fields in an example book store application.


Using custom fields in a sample application

In our real-life scenario, a simple online book store application, we use a document library to store documents about books and use custom fields to describe various properties of the books.

We then show how to create custom fields by creating property sheet types and document types, how to create a document with custom fields, and how to update the values in the custom fields.

Background

Our online book store uses Lotus Quickr to manage book information. We create documents for every book we have, and, to fully describe the book's information, we use custom fields as an extension of an ordinary document.

As stated above, in Lotus Quickr we describe custom fields by creating property sheet types. The properties in our property sheet type that describe a book are listed in table 3.

Table 3. Properties in the property sheet type
Property nameProperty type
CatalogString
ISBNString
PriceDecimal
Publish dateDate (default value is 1/1/99)
GenreSingle Choice (Fiction/Comic/Biography)

Figure 5 shows the Edit Property Sheet window in a Web UI.

Figure 5. Edit Property Sheet window
Edit Property Sheet window

We now add custom fields to the documents that describe the books by attaching the property sheet type to the book document. Figure 6 shows an example of a book document, with custom fields added, on a Web UI.

Figure 6. Book document with custom fields
Book document with custom fields

Preparing to use the demonstration example

To better explain the implementation, we provide a demonstration example, a pure Java program, in the Downloads section of this article. To use the sample program, first do the following:

  1. Create a place with the Library template in Lotus Quickr.
  2. Get the UUID of the library that you created in Step 1. Follow these steps:

    • Enter the library in a Web browser.
    • Click Subscribe to this library on the right side of the page; the library feed displays in the browser.
    • Note the URL in the browser navigation bar; it looks like this (the ID between “library” and “folder” is what we want):

      http://<host>:<port>/dm/atom/library/<uuid>/folder/.....

Now you are ready to use the program. Follow these steps:

  1. Extract the attachment example.zip in the Downloads section of this article, and edit the file example.properties in the directory target\classes, changing the value of server.base.url to

    http://<host>:<port>/dm/atom/library/<uuid>
  2. Change the value of user.name and user.password according to your Lotus Quickr server settings.
  3. Make sure that you have Java Development Kit (JDK) version 1.5.0 or later installed on your system, and then download Apache Abdera 0.4.0. The example requires Apache Abdera 0.4.0 to build and parse Atom XMLs and issue HTTP operations.
  4. To make it easier to use Abdera in the applications that follow, we set the Microsoft® Windows® environment variables ABDERA_HOME and ABDERA_CLASSPATH as shown in listing 5. If you are using Linux® or UNIX®, you need to call similar commands to set the environment variables.
Listing 5. Setting the ABDERA_HOME and ABDERA_CLASSPATH variables
Set ABDERA_HOME=<The folder where Abdera package is unzipped>
Set ABDERA_CLASSPATH=%ABDERA_HOME%/abdera-0.4.0-incubating.jar;%ABDERA_HOME%/
lib/axiom-api-1.2.5.jar;%ABDERA_HOME%/lib/axiom-impl-1.2.5.jar;%ABDERA_HOME%/lib/
commons-beanutils-1.7.0.jar;%ABDERA_HOME%/lib/commons-codec-1.3.jar;%ABDERA_HOME%/lib/
commons-collections-3.2.jar;%ABDERA_HOME%/lib/commons-httpclient-3.1-rc1.jar;
%ABDERA_HOME%/lib/commons-lang-2.3.jar;%ABDERA_HOME%/lib/commons-logging-1.0.4.jar;
%ABDERA_HOME%/lib/ezmorph-1.0.4.jar;%ABDERA_HOME%/lib/
geronimo-activation_1.0.2_spec-1.1.jar;%ABDERA_HOME%/lib/
geronimo-stax-api_1.0_spec-1.0.1.jar;%ABDERA_HOME%/lib/htmlparser-1.0.5.jar;
%ABDERA_HOME%/lib/jaxen-1.1.1.jar;%ABDERA_HOME%/lib/jetty-6.1.5.jar;
%ABDERA_HOME%/lib/jetty-util-6.1.5.jar;%ABDERA_HOME%/lib/json-lib-2.2.1-jdk15.jar;
%ABDERA_HOME%/lib/servlet-api-2.5-6.1.5.jar;%ABDERA_HOME%/lib/stax-api-1.0.1.jar;
%ABDERA_HOME%/lib/stax-api.jar;%ABDERA_HOME%/lib/wstx-asl-3.2.1.jar;%ABDERA_HOME%/lib/
xalan-2.7.0.jar;%ABDERA_HOME%/lib/xmlsec-1.3.0.jar;.

Running the demonstration example

Now you are ready to run the sample applications.

Application 1
com.ibm.clb.custom.field.example.CreateCustomFields

This application creates the property sheet types and document types described in this article's Background section. To run the application, go to the directory target\classes and enter the following command:

java –cp “%ABDERA_CLASSPATH%” com.ibm.clb.custom.field.example.CreateCustomFields

If all goes well, the application prints information about requests and responses exchanged between your client and the Lotus Quickr server. After the application exits, it saves the UUID of the property sheet type and document type that it created in the example.properties file. It might look like this:

created.pst.id=53791f0040f5e84eba81faa681ef10bf
created.doctype.id=bc6b918040f5e864ba82faa681ef10bf

NOTE: If you imported the example project into Eclipse or another Java Integrated Development Environment (IDE), you might need to manually synchronize the file example.properties from bin/classes (or where the built classes reside) to src/ (or where the source code resides).

You can also log in to the Lotus Quickr server from a Web browser to check the created property sheet type and document type.

Application 2
com.ibm.clb.custom.field.example.CreateDocumentWithCustomFields

This application creates an entry document with the property sheet type and document type that you created:

java –cp “%ABDERA_CLASSPATH%”
com.ibm.clb.custom.field.example.CreateDocumentWithCustomFields

NOTE: You must ensure that the properties created.pst.id and created.doctype.id are already in the example.properties file before you run this command.

This application also prints messages sent and received by the Lotus Quickr server. The last line of the printed message tells you the UUID of the document that we created:

document uuid: ce8f7000411626fdbab3faa681ef10bf

Make a note of the UUID; it is used as the input for the next example application.

Application 3
com.ibm.clb.custom.field.example.UpdateDocumentWithCustomFields

This application updates an existing document's custom fields, taking a document's UUID as its input:

java –cp “%ABDERA_CLASSPATH%”
com.ibm.clb.custom.field.example.UpdateDocumentWithCustomFields
<document-uuid>

In the following sections, we discuss programming details of these example applications.

Creating custom fields

To create custom fields, we must first create a property sheet type. As stated above, to do this step, we need to POST an Atom entry that represents a property sheet type to the property sheet type's Feed URL.

As described in the Managing custom fields using the REST programming model section, the key element in the property-sheet-type entry is the propertySheetTemplate XML in the entry's content element.

For example, for the property sheet type mentioned in the Background subsection, the propertySheetTemplate XML looks like that shown in listing 6.

Listing 6. PropertySheetTemplate XML document
<?xml version="1.0" encoding="UTF-8" ?>
  <meta:propertySheetTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:clb="http://content.ibm.com/clb/1.0" xmlns:
  meta="http://metadata.model.xsd.clb.content.ibm.com/1.0">
  <meta:property xsi:type="meta:ClbPropertyType" dataType="string" 
  maxLength="2048" multiple="false" propertyId="clb:ps1" 
  propertyName="clb:p_a6aa8d78-bc9e-4a35-a243-000aaaa8af12" readonly="false" 
  required="false" searchable="true">
    <meta:label label="Catalog" lang="en" />
    <meta:style name="ibm:textVariant" value="medium" />
  </meta:property>
    <meta:property xsi:type="meta:ClbPropertyType" dataType="string" 
    maxLength="254" multiple="false" propertyId="clb:ps2" 
    propertyName="clb:p_f4179b4b-9c29-45ea-a18b-3e507002015d" readonly="false" 
    required="false" searchable="true">
    <meta:label label="ISBN" lang="en" />
    <meta:style name="ibm:textVariant" value="medium" />
  </meta:property>
  
  <meta:property xsi:type="meta:ClbPropertyType" dataType="double" 
  multiple="false" propertyId="clb:ps3"
propertyName="clb:p_73020b22-ea33-4c14-b8dd-68791bdec517" readonly="false" 
required="false" searchable="true">
    <meta:label label="Price" lang="en" />
  </meta:property>

  <meta:property xsi:type="meta:ClbPropertyType" dataType="dateTime" 
  multiple="false" propertyId="clb:ps4" 
  propertyName="clb:p_c5c61619-44d7-4a12-bbba-9c5c7e245958" readonly="false" 
  required="false" searchable="true">
    <meta:label label="Publish Date" lang="en" />
    <meta:style name="ibm:dateVariant" value="date" />
    <meta:defaultValue>1999-01-01T00:00:00Z</meta:defaultValue>
  </meta:property>

  <meta:property xsi:type="meta:ClbPropertyType" dataType="string" 
  multiple="false" propertyId="clb:ps5" 
  propertyName="clb:p_946e09da-2e11-4bf8-9139-cb49c713bbe4" readonly="false" 
  required="false" searchable="true">
    <meta:label label="Genre" lang="en" />
    <meta:style name="ibm:selectionType" value="radio" />
    <meta:defaultValue>fiction</meta:defaultValue>
    <meta:option>
      <meta:value>fiction</meta:value>
      <meta:label label="Fiction" lang="en" />
    </meta:option>
    <meta:option>
      <meta:value>comic</meta:value>
      <meta:label label="Comic" lang="en" />
    </meta:option>
    <meta:option>
      <meta:value>biography</meta:value>
      <meta:label label="Biography" lang="en" />
    </meta:option>
  </meta:property>
</meta:propertySheetTemplate>

We need to prepare such an XML document in Java code and enter it into the property-sheet-type entry content. To keep it simple, in our example we construct this XML document by string concatenation; however, in a real-life project, you might need to use a Document Object Model (DOM) or a similar XML API.

The code snippet used to build the XML document is shown in listing 7. All the code is from the class com.ibm.clb.custom.field.example.CreateCustomFields in the source code of our example.

Listing 7. Code for building propertySheetTemplate XML
// start building propertySheetTemplate
StringBuilder pstTpl = new StringBuilder();
// add xml root tag start
pstTpl.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<meta:propertySheetTemplate xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
xmlns:clb=\"http://content.ibm.com/clb/1.0\" xmlns:
meta=\"http://metadata.model.xsd.clb.content.ibm.com/1.0\">");
pstTpl.append(new MetaPropertyElementBuilder().setDataType("string").
setMaxLength("2048").setPropertyId("clb:ps1").setLabelName("Catalog").
setStyleName("ibm:textVariant").setStyleValue("medium").build());
// ...similarly add other properties...

// add xml root tag end
pstTpl.append("</meta:propertySheetTemplate>");

The utility class MetaPropertyElementBuilder is used to build a <meta:property> element in the XML code. In this class, various attributes are aggregated to form a valid <meta:property> element. Note that the propertyName attribute is randomly generated by use of the class java.util.UUID.

After the propertySheetTemplate XML is ready, we put it into an ATOM entry, but first we must use Apache Abdera to generate the Atom entry. Follow these steps:

  1. Generate an empty entry, and then add <atom:category> to declare that it represents a property sheet type:

    Entry entry = abdera.newEntry();
    entry.addCategory("tag:ibm.com,2006:td/type", "propertySheetType",
    "propertySheetType");
  2. Set the title of the property sheet type:

    String pstTitle = "custom-fields-example-" + System.currentTimeMillis();
    entry.setTitle(pstTitle);
  3. Set the generated propertySheetTemplate XML to the entry's content:

    entry.setContent(pstTpl.toString());

    In this step, Abdera does some String manipulation to escape XML characters. If you print the entry at this time, it looks strange.

  4. Finally, we prepare the HTTP request and POST it to the property-sheet-type feed URL:

    RequestOptions opt = new RequestOptions();
    opt.setUseChunked(false);
    opt.setContentType("application/atom+xml");
    ClientResponse response = client.post(loader.getPstFeedUrl(), entry, opt);

The call succeeds if all is OK with the server, which responds with 201 Created. We can read the status code in the response object received from the HTTP POST call. We can also get the entry for the created property sheet type from the response:

Entry retPstEntry = (Entry) response.getDocument().getRoot();
String retPstId = Utils.getUuidFromEntry(retPstEntry);

After the property sheet type is created, we must add it to a document type, so that we can use this property sheet type as custom fields in a document. This step is done using an HTTP POST call to the document type's feed URL.

It's easy to create such a document type: Create an Atom entry and put in the returned property sheet type UUID as the <td:propertySheetType> element, as shown in listing 8.

Listing 8. Create document type Atom entry and set property sheet type
entry = abdera.newEntry();
entry.addCategory("tag:ibm.com,2006:td/type", "documentType", "documentType");
String docTypeTitle = "doctype-example-" + System.currentTimeMillis();
entry.setTitle(docTypeTitle);
// extension elements for doctype
ExtensibleElement el = entry.addExtension("urn:ibm.com/td", "propertySheetType", "td");
el.setText(retPstId);

The entry is ready. We need to POST it to the server to create it.

We've now created a property sheet type and a document type containing it. Our custom fields are ready to use.

Creating a document with custom fields

Because we already have a property sheet type to describe our custom fields and have added it to a document type, we can create documents with the custom fields.

Let's create a document using an HTTP POST command to a library feed URL and demonstrate the creation of an Atom Entry with custom fields as an example. The code in the following steps is from com.ibm.clb.custom.field.example.CreateDocumentWithCustomFields.

  1. Start by constructing an ordinary document entry:

    Entry entry = abdera.newEntry();
    entry.addCategory("tag:ibm.com,2006:td/type", "document", "document");
    entry.setTitle("document-example-" + System.currentTimeMillis());
    entry.setSummary("A test piece of entry.");
  2. Next, tell the server to attach the document type to the document. Remember that we can do this step by attaching the documenttype parameter to the URL or by adding an element to document entry as a <td:documenttype> element. Here we use the latter method:

    ExtensibleElement el = entry.addExtension("urn:ibm.com/td", "documenttype", "td");
    el.setText(loader.getCreatedDoctypeId());

    Now the document is attached with the custom fields that we have defined.

    We can now give values to each field by adding an <snx:field> element to the document entry. Like the propertySheetTemplate XML code in our example, we build the <snx:field> by String concatenation. Again, for real-world projects, consider using XML APIs, such as DOM.

  3. First, we find the property information from the propertySheetTemplate XML by designating its property ID:

    ExtensibleElement customFieldEl =
    Utils.findCustomFieldElementByPropertyId(pstTplEl, "clb:ps1");
    where the utility method findCustomFieldElementByPropertyId() searches a property by its property ID over all created properties in propertySheetTemplate.
  4. Finally, we build the <snx:field> element by putting property and property-sheet-type information together as required (recall table 2):

    new SnxFieldBuilder(entry).setFid(customFieldEl.getAttributeValue
    ("propertyName")).setName(pstName).setPstId(pstId).setType
    ("string").setValue("1, prelude\n2, middle\n3, end. " +
    System.currentTimeMillis()).build();

That's it for constructing the Atom entry representing the document with custom fields. The complete document entry is shown in listing 9.

Listing 9. POSTed document entry with <snx:field>
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:td="urn:ibm.com/td" 
xmlns:snx="http://www.ibm.com/xmlns/prod/sn">
  <category term="document" scheme="tag:ibm.com,2006:td/type" 
  label="document" />
  <title type="text">document-example-1263702859296</title>
  <td:documenttype>62a16d0041064cd6ba95faa681ef10bf</td:documenttype>
  <summary type="text">A test piece of entry.</summary>
  <snx:field fid="clb:p_a6aa8d78-bc9e-4a35-a243-000aaaa8af12" 
  name="custom-fields-example-1263378081261" pstId="f0c0280041064cc3ba94faa681ef10bf" 
  type="string">1, prelude
2, middle
3, end. 1263702859359</snx:field>
  <snx:field fid="clb:p_f4179b4b-9c29-45ea-a18b-3e507002015d" 
  name="custom-fields-example-1263378081261" pstId="f0c0280041064cc3ba94faa681ef10bf" 
  type="string">1-2-3-4</snx:field>
  <snx:field fid="clb:p_73020b22-ea33-4c14-b8dd-68791bdec517" 
  name="custom-fields-example-1263378081261" pstId="f0c0280041064cc3ba94faa681ef10bf" 
  type="double">12.34</snx:field>
  <snx:field fid="clb:p_c5c61619-44d7-4a12-bbba-9c5c7e245958" 
  name="custom-fields-example-1263378081261" pstId="f0c0280041064cc3ba94faa681ef10bf" 
  type="date">2010-01-07T20:32:00Z</snx:field>
  <snx:field fid="clb:p_946e09da-2e11-4bf8-9139-cb49c713bbe4" 
  name="custom-fields-example-1263378081261" pstId="f0c0280041064cc3ba94faa681ef10bf" 
  type="string">comic</snx:field>
</entry>

The entry is ready. We POST it to the server using code similar to the code used when posting property sheet types and document types. The server responds with a 201 Created message, if creation is successful. You can get the created document entry from the response object.

NOTE: This example has shown how to create a document using an Atom entry; however, with Lotus Quickr REST document service, we can also create a document with custom fields by uploading the document binary content.

To do this task, first upload the document binary with the appropriate document type and then update the document with <snx:field>. For more details about how to create a document by uploading the binary content, see the Documents Services topic in the Lotus Quickr wiki.

http://www-10.lotus.com/ldd/lqwiki.nsf/dx/documents-services

Updating a document with custom fields

Updating a document with custom fields is quite similar to creating one. To do this task, build a document entry and send it by an HTTP PUT command to the document entry URL, such as:

http://<host>:<port>/dm/atom/library/<lib-id>
/document/<document-id>/entry

Here we get an existing document's entry with custom fields and then update the fields. It is also possible to build the fields from scratch, if the correct document UUID is included in the document entry.

To get the document entry, we use an HTTP GET command to the document entry URL:

ClientResponse response = client.get(loader.getDocumentEntryUrl(docId));
Entry docEntryWithPropertySheet = (Entry) response.getDocument().getRoot();

As when creating the document, we update custom fields by putting them in the document entry as <snx:field>:

ExtensibleElement customFieldEl =
Utils.findCustomFieldElementByPropertyId(pstTplEl, "clb:ps3");
new SnxFieldBuilder(docEntry).setFid(customFieldEl.getAttributeValue
("propertyName")).setName(pstName).setPstId(pstId).setType
("double").setValue("15.57").build();

You need to include only the updated fields in the document Atom entry when updating the document; in the preceding code snippet, we updated the Price field.

Next we PUT this updated entry to the server:

RequestOptions opt = new RequestOptions();
opt.setUseChunked(false);
opt.setContentType("application/atom+xml");
response = client.put(loader.getDocumentEntryUrlWithLockTrue(docId), docEntry, opt);

The server responds with a 200 OK message, if the update is successful, and the updated document entry is included in the response.


Conclusion

In this article, we introduced the concept of custom fields support in the Lotus Quickr 8.1.1 REST document service. We discussed the programming model in the REST document service and demonstrated how to use it through a simple book store application by doing the following steps:

  • Creating a property sheet type that includes custom fields
  • Creating a document type that is associated with the property sheet type
  • Creating a document with custom fields by associating a document type and specifying property values in an Atom Entry
  • Updating custom fields of a document

Based on the custom field support provided by the REST document service, users can develop their own applications that can work with custom fields in Lotus Quickr.


Download

DescriptionNameSize
Code sampleexample.zip28KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into IBM collaboration and social software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus
ArticleID=468873
ArticleTitle=Managing custom fields using the REST document service in IBM Lotus Quickr 8.1.1 services for WebSphere Portal
publish-date=02232010