Skip to main content

IBM Lotus Quickr library linker: Content interoperations between Lotus Quickr libraries based on Dojo and Lotus Quickr REST services

Hui Jian (Jeff) Je (hehuij@cn.ibm.com), Software Engineer, IBM
Hui Jian He (Jeff) is a Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach Jeff at hehuij@cn.ibm.com
Qin (Alice) Jun (qinjun@cn.ibm.com), Software Engineer, IBM
Qin Jun (Alice) is a Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach Alice at qinjun@cn.ibm.com
Yan (Kevin) Tao (taoyan@cn.ibm.com), Software Engineer, IBM
Tan Tao (Kevin) is a Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach Kevin at taoyan@cn.ibm.com.
Chen Yan (cheny@cn.ibm.com), Advisory Software Engineer, IBM
Chen Yan is an Advisory Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach him at cheny@cn.ibm.com.
Bruce Roberts is an Architect of IBM Lotus Quickr. You can reach Bruce at robertsb@us.ibm.com.

Summary:  Learn how to operate your Lotus Quickr library content with Lotus Quickr REST services based on Dojo. In this example described in this article, content from different Lotus Quickr libraries interacts with simple Lotus Quickr REST services in the library linker tool, which is based on the latest Dojo 1.0 framework.

Date:  29 Apr 2008
Level:  Intermediate
Activity:  3031 views

IBM® Lotus® Quickr™ content libraries can help you easily organize and share content for your projects, with your teams, or for yourself. You can set up libraries for your documents so that your teams can easily share and collaborate with check-in and check-out, version control, and other tools to help manage content. Complex and powerful workflow also simplifies working with content.

Individual content operations between different Lotus Quickr content libraries are not easy, though. In this example, content from different Lotus Quickr libraries interacts with simple Lotus Quickr REST services in the Library Linker tool. Library linker is based on the latest Dojo 1.0 framework. Contents are listed in two Dojo grid widgets, and you can work with two libraries on the same page.

Prerequisites

You should have a good understanding of IBM Lotus Quickr REST services and some knowledge of Dojo toolkit and HTML development. See the developerWorks® article, "Introducing IBM Lotus Quickr REST services," for more information about Lotus Quickr REST services. See the Dojo Web site for more information about Dojo.


About Lotus Quickr Library Linker

Lotus Quickr manages your organization’s contents with a library approach. Users, though, inevitably need to work with contents in different libraries; for example, they might want to copy documents from one library to another. The current version of Lotus Quickr does not support this kind of use with a browser. Lotus Quickr Library Linker is designed to help us in this case.

Figure 1 shows the user interface (UI) of Lotus Quickr library linker.


Figure 1. Lotus Quickr library linker
Lotus Quickr library linker

The contents of two Lotus Quickr libraries are listed after the user clicks the Get Contents buttons. The contents contain both folders and documents in a library. The two libraries can be on the same server, or they can be on different servers. You can copy the selected contents in the source library to the target library by clicking the >> button or the << button. Detailed implementation steps for installing and using Lotus Quickr library linker follow.


Get content from two different libraries

In this case, we need to get the contents to refresh the table without refreshing the whole page. This requirement can be satisfied by calling an Ajax request. Currently there are too many implementations to support Ajax, such as Bindows, BackBase, Dojo, Open Rico, Tibet, and others. In this case, we choose Dojo as our Web framework because Dojo is an open source framework that is based on JavaScript™ and that provides many ready-made widgets.


Build the grid table for the UI display

A grid table, which is a widget in Dojo1.0, provides a convenient way to list all contents, to sort the contents according to the columns, and to collect the user’s selections. Add this grid table in your HTML page as shown in listing 1.


Listing 1. Code snippet to define the grid table in the HTML file
<div style="border:grey solid 1px;" id="gridLeft" dojoType="dojox.Grid"
structure="layout" model="modelLeft" autoHeight="true">
</div>

In listing 1, the variable structure is an object to display the table’s layout, such as the column’s name and style. Listing 2 shows the code that defines the variable structure.


Listing 2. Code snippet to define the variable structure
var view = {
	cells: [[
		{name: 'Select', width: 5, headerStyles: 'padding-bottom: 2px;', 
		formatter: format4Select, styles: 'padding: 3px; text-align: center;'},
		{name: 'Category', width: 5, headerStyles: 'padding-bottom: 2px;', 
		formatter: format4Category, styles: 'padding: 3px; text-align: center;'},
		{name: 'Title', width: 15, headerStyles: 'padding-bottom: 2px;', 
		styles: 'padding: 3px;font-weight:bold;'},
		{name: 'Link', width: 100, headerStyles: 'padding-bottom: 2px;', 
		styles: 'text-align: left; padding: 3px;'}
		]]};

// a grid structure is an array of views.
var layout = [ view ];

You use the variable model to maintain the data to be displayed. See listing 3.


Listing 3. Code snippet to define the variable model
var data = [[“0”, “folder”, “test1”, “”],
 		[“0”, “document”, “test2”, “”]];
var modelLeft = new dojox.grid.data.table(null, data);


Get the contents from the library

When the user clicks the button labeled Get Contents, the Lotus Quickr library feeds REST service is called through an Ajax mechanism to get all the contents from the library. The response takes the form of Atom. Lotus Quickr has an internal Atom parser based on the Dojo DOM and Atom formats. It can also be parsed with the JavaScript DOM. The calling method can look like the code shown in listing 4.


Listing 4. Getting contents from library with the Atom library
getDataFromServer: function(url,user,pw,callback)
{
    var atomIO = new ibm_atom.io.atom.AtomIO();
    //Here we wrapped the Atom parser as AtomIO with Javascript DOM.
    atomIO.user = user;
    atomIO.password = pw;
    //get content from server
    atomIO.getFeed(url, feedHandler, errorHandler);        
    data = new Array();
    //The feedHandler function will be called on a successful response.
    function feedHandler(feed, domNode)
    {
        if (feed != null)
        {
            var entries = feed.entries;
            if (entries != null)
            {
                for (var i = 0; i < entries.length; i++)
                {
                    var entry = entries[i];
                    var newArray = new Array();
                    newArray[0] = "0";
                    newArray[1] = entry.categories[0].term;
                    newArray[2] = entry.title.value;
                    newArray[3] = getCurrentLink(entry);
                    newArray[4] = entry.id;
                    data[i] = newArray;
                }
            }
            //callback to refresh UI
            if (callback)
            {
                eval(callback).call(null, this);
            }
        }

    }
    //The errorHandler function will be called on an unsuccessful response.
    function errorHandler(error, ioArgs)
    {
        alert(error.message);
    }
}

The following list introduces the code of listing 4:

  1. url. The feed’s URL to denote content in the Lotus Quickr server.
  2. user. User name to access the content.
  3. pw. Password to access the content.
  4. callback. Callback method to refresh the UI when the user gets a successful response.
  5. Ibm_atom.io.atom.AtomIO. Object provided in the IBM Atom Library package that provides a series of methods to support Atom requests and responses.

Dojo supports the Ajax request itself so that you can get Lotus Quickr library contents through the Dojo XmlHttpRequest Method directly as shown in listing 5.


Listing 5. Getting contents from the library through the Dojo XmlHttpRequest method
function getFeed(feedUrl, user, pw) 
{
  dojo.xhrGet( {
    // The following URL must match that used to test the server.
    url: feedUrl, 
    user: user,
    password: pw,
    handleAs: "xml", 
	 	preventCache: true, //do not user browser's cache
    timeout: 5000, // Time in milliseconds
  
    // The LOAD function will be called on a successful response.
    load: function(response, ioArgs) {
      alert("Success response is " + response);
      return response;
    },
  
    // The ERROR function will be called in an error case.
    error: function(response, ioArgs) {
      console.error("HTTP status code: ", ioArgs.xhr.status);
      return response; 
      }
    });
}


Refresh the grid table

After getting the contents by parsing the Atom XML response through the Atom Library or Dojo DOM, construct the content data in an array and refresh the grid table with this data. See listing 6.


Listing 6. Callback method used to refresh the UI
function callback(data)
{
    gridLeft.model.clearData();
    
    //data is an Array.
    if(data != null)
    {
        gridLeft.model.setData(data);
        gridLeft.refresh();
        
        //clear the user's selections.
        gridLeft.selection.clear();
    }
} 

With the same process, you can get the other library's contents and list them in the Grid table.


Save contents from source to target

Lotus Quickr provides a suite for REST services to work with documents in a Lotus Quickr library doing such functions creating, editing, and deleting documents. More information can be found in the developerWorks Lotus article, "Introducing IBM Lotus Quickr REST services."

In Lotus Quickr library linker, both of the libraries on the page can be seen as either a source or a target library. First the user selects content by clicking the checkboxes. Then, the user clicks the << button or the >> button to copy the contents from one library to another.

These contents can be folders or documents. The code flow should be as follows:

  1. Get the entry/feed URL of the selected contents.
  2. Perform a GET request with the URL in step 1 on the source library to get the metadata or attachment (if the content type is a document) of the content.
  3. Organize the POST entry Atom XML according to step 2.
  4. Perform a POST request on the target library to publish the new content.

There are two types of content: documents and folders. Here, we describe the detailed steps to handle these two content types.

Save a document

In Lotus Quickr, the document entry contains the metadata of the document, and the URL pattern to get a document entry is as follows:

<protocol>://<host>:<port>/dm/atom/library/<library uuid>/document/
<document uuid>/entry

We can get the link to the document’s attachment from the document entry with rel="edit-media". The link should look like this:

<link href="http://lwptsthink10.cn.ibm.com/dm/atom/library/
03557c004823e048951db5c52d6a3bea/document/757104804838726f964ab7c52d6a3bea/media"
rel="edit-media" />

To save a document, you need to save not only the metadata that includes the name, document type, and so on but also the attachment. In Lotus Quickr, the attachment of a document is transformed as a binary stream; we can get the binary stream with the media URL, and then we can post it to the target library with the Lotus Quickr document POST service as shown in listing 7. Listing 8 shows the code used to get an attachment from a document.


Listing 7. Document POST service
POST /library/08ca5f0044ab2d6a858eed71ca20d4cf/folder
/4e05cb0044f7e4f1937e932188721110/entry HTTP/1.1
Host: example.com
Content-Type: application/msword
Content-Length: ……
Authorization: Basic ……
Slug: My document.doc
Binary of the document goes in the request body


Listing 8. Getting attachment from a document
function getDocHandlerL2R(entry, domNodes)
{
	var docTitle = entry.title.value;
	var entryLinks = entry.links;
	
	var docMedia = getMediaLink(entryLinks);
	getDocumentAttachment(docTitle, docMedia, "Right");
}

function getDocumentAttachment(docTitle, docUrl, position) {
 dojo.xhrGet({
 	url: docUrl,
	handleAs: "text",
	load: function(responseText)
	{
		console.log("Get Document Attachment Successfully!");
		postDocumentAttachment(responseText, position, docTitle);
	 },
	 error: function(response)
	 {
	 	console.log("Get Document Attachment Fail!");
	 }
	});
}
function getMediaLink(links)
{
	if(links === null || links.length === 0){
			return null;
		}
		for(x in links){
			if(links[x].rel && links[x].rel == "edit-media"){
				return links[x].href;
			}
		}
		return null;
}

In listing 8, we get the title of document and the URL of its attachment from the document entry, and the URL can be used to get the binary stream through dojo.xhrGet function. See listing 9 for the code that posts the attachment to the target library.


Listing 9. Posting the attachment to the target library
function postDocumentAttachment(data, position, docTitle)
{
	dojo.rawXhrPost({
		url: feedUrl = dojo.byId("libFeed" + position).value,
		postData: data,
		handleAs: "text",
		contentType: "text/plain",
		encoding: "utf-8",
		headers: {"Slug": docTitle},
		load: function(responseText)
		{
			console.log("Post Document Attachment Successfully!");
			getContent(position);
		},
		error: function(response){
			console.log("Post Document Attachment Error!");
		}
	});
}

Save a folder

To save a folder, you need to create a new folder in the target library and copy all the subdocuments and subfolders into it. Here, we describe how to create a new folder in the library. To save an entire folder and its contents, you need to traverse all the content of the source folder.

You can find the metadata of a folder in its folder entry. The URL pattern of a folder feed should look like this:

<protocol>://<host>:<port>/dm/atom/library/<library uuid>/folder/
<folder uuid>/entry

See listings 10 and 11 for code for the folder entry Atom XML and the code for saving a folder to a target library.


Listing 10. Code snippet for folder entry Atom XML
<entry xml:base=”http://example.com/dm/atom/library/5d06ab0044ed8129bd5ebd4caeec5df1/”
xmlns=”http://www.w3.org/2005/Atom”>

  <id>urn:lsid:ibm.com:td:a054ab0044f7e2a9936d932188721110</id>

  <link href=”folder/a054ab0044f7e2a9936d932188721110/entry” rel=”self”/>
  <link href=”http://example.com/wps/mypoc?uri=
  dm:a054ab0044f7e2a9936d932188721110&verb=view” rel=”alternate”/>
  <link href=”folder/a054ab0044f7e2a9936d932188721110/entry” rel=”edit”/>

  <category term=”folder” scheme=”tag:ibm.com,2006:td/type” label=”folder”/>

  <author>
    <uri>uid=jsmith,ou=example,o=organization</uri>
    <name>John Smith</name>
    <email>jsmith@example.com</email>
  </author>

  <title type=”text”>My Folder</title>
  <published>2007-04-13T22:16:42.734Z</published>
  <updated>2007-04-13T22:16:42.734Z</updated>

    <!-- User modifiable creation date -->	
    <td:created>2007-05-13T19:03:25.500Z</td:created>

    <!-- User modifiable modification date -->	
    <td:modified>2007-05-13T19:03:25.500Z</td:modified>

    <!-- Last modified person -->
    <td:modifier>
      <td:uri> uid=jdoe,ou=example,o=organization</td:uri>
      <td:name>John Doe</td:name>
      <td:email>jdoe@example.com </td:email>
    </td:modifier>

  <summary type=”text”>My Folder description</summary>

  <content type=”application/atom+xml” 
  src=”folder/a054ab0044f7e2a9936d932188721110/feed”/>

</entry>


Listing 11. Code snippet for saving folder to target library
function folderHandlerR2L(feed, domNodes)
{
	var folderTitle = feed.title.value;
	//create a new folder
	createNewFolder(folderTitle, "Left");
}
//create a new folder
function createNewFolder(folderTitle, position)
{
	//organize the new folder entry for creating operation
	var folderEntry = folderEntryHeader.concat(folderTitle, folderEntryEnd);
	//add the new folder to another library
	postNewFolder(folderEntry, position);
}

//add the new folder to target library
function postNewFolder(entry, position)
{
	dojo.rawXhrPost({
		url: feedUrl = dojo.byId("libFeedTarget" + position).value,
		//This URL is the feed url of the target library/folder.
		postData: entry,
		contentType: "application/atom+xml",
		headers: {"Slug": "Folder Name"},
		load: function(responseText){
			console.log("create a new folder successfully!");
			getContent(position);
		},
		error: function(){
			console.log("Get Folder Feed Fail!");
		}
	});
}


Conclusion

In this document, we showed you how to operate your Lotus Quickr library content with Lotus Quickr REST services based on Dojo. As a content management and collaboration platform, Lotus Quickr REST services offer an easy way for your organization to extend Lotus Quickr capability and perform mashups with your existing system.



Download

NameSizeDownload method
QuickrLibraryLinker.zip56.2KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the authors

Hui Jian He (Jeff) is a Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach Jeff at hehuij@cn.ibm.com

Qin Jun (Alice) is a Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach Alice at qinjun@cn.ibm.com

Tan Tao (Kevin) is a Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach Kevin at taoyan@cn.ibm.com.

Chen Yan is an Advisory Software Engineer at IBM working with the Lotus Quickr team in the China Software Development Lab in Beijing, You can reach him at cheny@cn.ibm.com.

Bruce Roberts is an Architect of IBM Lotus Quickr. You can reach Bruce at robertsb@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus
ArticleID=304831
ArticleTitle=IBM Lotus Quickr library linker: Content interoperations between Lotus Quickr libraries based on Dojo and Lotus Quickr REST services
publish-date=04292008
author1-email=hehuij@cn.ibm.com
author1-email-cc=
author2-email=qinjun@cn.ibm.com
author2-email-cc=
author3-email=taoyan@cn.ibm.com
author3-email-cc=
author4-email=cheny@cn.ibm.com
author4-email-cc=
author5-email=robertsb@us.ibm.com
author5-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers