...

Developing an IBM® Lotus® Quickr™ Firefox connector using Quickr services

by user

on
Category: Documents
64

views

Report

Comments

Transcript

Developing an IBM® Lotus® Quickr™ Firefox connector using Quickr services
Developing an IBM® Lotus® Quickr™ Firefox
connector using Quickr services
Shun Zhang
IBM Software Group
Software Engineer
IBM, Beijing, China
Hui Jian He
IBM Software Group
Software Engineer
IBM, Beijing, China
April 2009
© Copyright International Business Machines Corporation 2009. All rights reserved.
Abstract: This article explains, step by step, how to build a customized Mozilla
Firefox connector for IBM® Lotus® Quickr™, using Lotus Quickr Representational
State Transfer (REST) services. All the source code for the example is provided.
Contents
1.
2.
3.
4.
5.
5.1
5.2
5.3
5.4
5.5
5.6
6.
7.
8.
Overview..........................................................................................................2
Lotus Quickr content services ..................................................................2
Firefox extensions ........................................................................................3
Quickr Connector for Firefox.....................................................................4
Anatomy of the Quickr Firefox Connector .............................................5
Getting started ..............................................................................................5
Deploy the extension to Firefox...............................................................6
Add a menu item to launch the connector extension ........................8
The connector’s main UI............................................................................9
Initialize connector ....................................................................................12
Tree implementation .................................................................................13
Conclusion....................................................................................................22
Resources .....................................................................................................22
About the authors .......................................................................................22
1. Overview
IBM Lotus Quickr is Web 2.0-based team collaboration software for knowledge
sharing and collaboration. It includes a content repository, content management and
team collaboration capabilities, and connectors that allow you to access Lotus Quickr
from within desktop applications.
Quickr connectors enable users to work with documents on a Lotus Quickr server
from familiar desktop applications such as IBM Lotus Notes®, IBM Lotus
Sametime®, Microsoft® Windows® Explorer, Microsoft Outlook, Microsoft Office
and Lotus Symphony™.
Quickr connectors interact with Lotus Quickr content using a set of published remote
Simple Object Access Protocol (SOAP) and REST interfaces. Lotus Quickr
encourages customers or business partners to build applications on these open
interfaces.
This article presents an example of how to use these service interfaces to build a
custom connector. We select Firefox as the base application sample because Firefox is
designed to be extensible with a rich programming interface; moreover, there is a
mature developer community.
With this Firefox connector, customers can manipulate their documents from multiple
Quickr servers in a Firefox browser. Also, since Firefox is cross platform, it is the first
connector that can run on non-Windows platforms. And since Lotus Quickr, IBM
FileNet® Content Manager Collaboration Edition, and IBM Content Manager
Collaboration Edition also provide the same suite of remote services, this connector
can also work with all these servers.
2. Lotus Quickr content services
Quickr content services make it possible to create, manage, update, search, query, and
delete Quickr content, enabling users to access and manipulate content in Lotus
Quickr.
Lotus Quickr REST Services are designed around open standards and Web 2.0
technologies, allowing you to build applications with a basic understanding of
existing Web technologies, such as HTTP and XML.
The services are based on the Atom Syndication Format, as described in RFC 4287
for accessing content from Lotus Quickr, and on the emerging Atom Publishing
Protocol as described in RFC 5023 for publishing content to Lotus Quickr. See the
developerWorks article, Introducing IBM Lotus Quickr REST services, for more
information about the REST services.
Currently Lotus Quickr provides the services as shown in table 1.
Table 1. Lotus Quickr services
Release Service
Supports the ability to:
8.0
Document services
Manipulate document-oriented component types (Document Library)
8.0
Search services
Discover information across multiple content component types
8.1
Place services
Manipulate collaboration component containers
8.1
Template services
Manipulate initial structure of places
8.1
Policy services
Control server resource usage
8.1
Web Content
services
Control Web content
In this connector we use the Document services. If you’d like to extend the Firefox
connector with other services, you can leverage all the above services shown in table
1.
3. Firefox extensions
Firefox provides an extensibility model to allow third-party code modules, called
extensions, to modify the core browser's functionality or appearance and to add new
features or user interface (UI) elements.
An extension consist of three parts: (1) XUL documents, which describe the layout of
the UI, (2) CSS directives that define the appearance of interface elements, and (3)
Java™Script code that determines the behavior of such elements. For more
information, refer to the Mozilla Extensions page.
The connector extension architecture is as follows (see figure 1):
•
XUL UI. Uses XUL language to define the connector UI, including launch menu
item, main UI, context menu, add library dialog, and property dialog.
•
Control Module. Interacts with user interface (UI) inputs and the IO module,
accepts user’s input and drive IO module to fetch data from the remote server, and
then parses data for presenting in the UI. JavaScript is the implementing language.
IO Module. First it communicates with the server to get/post Atom feed/entry using
IBM dojo Atom extensions. Then it reads/writes libraries information storied in local
file systems, using the Mozilla programming interface.
Figure 1. Firefox connector architecture
This connector supports four types of servers now. In addition, IBM Business Partners
have implemented the Quickr Content Services on other platforms (see the Lotus
Business Partners and Solutions Catalog for more information about these solutions).
Note that the Quickr services for Domino implementation should be version 8.2 or
later.
4. Quickr Connector for Firefox
The Lotus Quickr Connector for Firefox is a Firefox extension that provides many of
the features of Lotus Quickr connectors. It lists document libraries by server, it can
filter libraries by library name, and can easily interact with the Quickr Web UI.
The main features of this connector are as follows:
Servers/platforms supported:
• Servers: Lotus Quickr, IBM FileNet Content Manager Collaboration Edition,
IBM Content Manager Collaboration Edition
• OS: All platforms on which Firefox can run
Basic connector operation:
• Browse library contents
• Send content via mail
• Download document
• Drag and drop documents across libraries from multi-servers
More:
• Bookmark favorite content
• Drag and drop Web elements (for example, images from Google) to library
directly
See the download, “Screen record of Lotus Quickr connnector for Firefox,” for a
demonstration.
5. Anatomy of the Quickr Firefox Connector
Now let’s discuss the essentials of the Firefox Connector.
5.1
Getting started
First, you may want to familiarize yourself with the basic concepts and technical
requirements for building a Firefox connection by visiting Mozilla.org and reviewing
“Building an Extension”.
Then, to deploy the source code for the Quickr Connector, follow these steps:
1. Create an empty project using your favorite Integrated Development
Environment (IDE). The project name can be [email protected].
2. Download the [email protected] file from the Downloads
section.
3. Extract all the files to the root folder of the project. The project hierarchy
should look something like that shown in figure 2.
Figure 2. Project directory structure
All the XUL and JavaScript files are in the content folder, the i18n files are in the
locale folder, and the images and CSS files are in the skin folder.
The files Chrome.manifest and install.rdf are required for an extension to be
recognized and run by Firefox, and those two files should be in the root folder of
the project. The creation of the files is described in section 5.2 below.
5.2
Deploy the extension to Firefox
Before deploying the extension to Firefox, we need to look in the chrome.manifest
and install.rdf files mentioned above, and then create a link file to the extension
project under the Firefox extension directory.
chrome.manifest
chrome.manifest is under the project root directory, and the contents are shown in
listing 1.
Listing 1. chrome.manifest contents
content
quickrconnector
content/
overlay
chrome://browser/content/browser.xul
chrome://quickrconnector/content/overlay.xul
locale quickrconnector
en-US
locale/en-US/
locale quickrconnector
zh-CN
locale/zh-CN/
skin
quickrconnector
classic/1.0
skin/
The content element says that, for a chrome package quickrconnector, we can find its
content files at the location content/ (note that the “/” is required), which is a path
relative to the location of chrome.manifest.
We need Firefox to merge our overlay with the browser window whenever it displays
one. So add the overlay element to tell Firefox to merge overlay.xul into browser.xul
when browser.xul loads. Since we have only one launch entry, we just add one overlay
element.
The locale elements describe the languages supported by the connector, and the skin
element describes which skin to use.
install.rdf file
install.rdf is also under the project root directory, and the contents are shown in listing
2.
Listing 2. install.rdf contents
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>[email protected]</em:id>
<em:name>Quickr Connector Demo</em:name>
<em:version>1.0.6</em:version>
<em:description>Lotus Quickr Connector Firefox
Plugin</em:description>
<em:creator>Sean Zhang</em:creator>
<em:contributor>Jeff He</em:contributor>
<em:homepageURL>http://quickr.tap.ibm.com</em:homepageURL>
<!-- Firefox -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>1.5</em:minVersion>
<em:maxVersion>3.0.*.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
The connector’s em:id element must be a GUID or in the form of an email address
(whether valid or not). The em:id of the target application is Firefox’s ID, which is
fixed.
Create a link file
To deploy the extension, create a file named [email protected] (notice this is
the same name as the em:id from the install.rdf file) in the <Firefox installation
path>/extensions directory and edit the file, adding the project folder’s path as its
contents.
Test and debug
So far we’ve performed all the steps to deploy a simple extension. When you restart
Firefox, you should find the Quickr Connector menu item under the Tools menu, and
the sidebar should open with the main UI XUL file quickrconnector.xul.
To debug the Firefox extension, first set up an extension development environment,
such as the Extension Developer's extension, to save time when you reload the XUL
changes. Otherwise, you must restart the Firefox application.
See the Mozilla development center for more information about chrome.manifest,
install.rdf, and building a Firefox extension.
5.3
Add a menu item to launch the connector extension
Now that you have a basic idea about how the Firefox connector extension is built and
deployed, let’s discuss how to add the menu item to launch the connector.
First we need to create an overlay XUL file to add the Quickr menu item to the Tools
menu. The file is in the content directory with the name overlay.xul, and the contents
are shown in listing 3.
Listing 3. XUL file contents
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://quickrconnector/skin/overlay.css"
type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://quickrconnector/locale/overlay.dtd">
<overlay id="quickrconnector-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul
">
<menupopup id="menu_ToolsPopup">
<menuitem observes="viewQuickrSidebar" label="&quickrconnector;"
accesskey="&quickrconnector.accesskey;"
key="key_gotoQuickrConnector"/>
</menupopup>
<broadcasterset id="mainBroadcasterSet">
<broadcaster id="viewQuickrSidebar" autoCheck="false"
sidebartitle="&quickrconnector;" type="checkbox"
group="sidebar"
sidebarurl="chrome://quickrconnector/content/quickrconnector.
xul"
oncommand="toggleSidebar('viewQuickrSidebar');"/>
</broadcasterset>
</overlay>
This file tells Mozilla to load locale file chrome://quickrconnector/locale/overlay.dtd,
add a menu item to the Tools menu at the end by default, and then define the action of
this menu item.
toggleSidebar is a built-in function to open the sidebar. The sidebarurl attribute refers
to the connector main UI XUL; when the menu item is clicked, the sidebar will open
with sidebarurl. We’ll talk about the main UI in detail later.
Locale file
If you look in the menuitem element in overlay.xul, you will find the label and
accesskey attributes’ values start with “&” and end with “;”. That means the actual
value of this attribute comes from a locale file, and the present string between “&”
and “;” is just a key to get that value.
To support a certain languages and locale, you need to create a corresponding locale
file. For example, to support English in the United States, create an en-US folder
under the locale directory, create the overlay.dtd file mentioned above, and input the
following contents:
<!ENTITY quickrconnector "Quickr Connector">
<!ENTITY quickrconnector.accesskey "Q">
5.4
The connector’s main UI
The main UI inside the sidebar is an XUL page (see figure 3). The file
quickrconnector.xul is under the content directory. Of course, since there must be
some localized text in the UI, quickrconnector.dtd is used to store locale key-value
pairs data in the corresponding locale directory.
Figure 3. Connector extension main UI
There are four parts of the sidebar:
•
Title. Actually, the title isn’t set in the main UI XUL; instead, it’s set when the
launch menu item is clicked.
•
Toolbar. hbox is a container that can group elements horizontally. The first
functional element is a timeout textbox and, since its timeout attribute is set to
500ms, the oncommand action will be triggered every 500ms when editing the
textbox.
Then we add two image elements and set their onclick value to addLibrary and
collapseAll as shown in listing 4. (You’ll know what they do when they are
clicked by the function name.)
Listing 4. Toolbar contents
<hbox align="center">
<label value="&find.label;" control="search-box"/>
<textbox id="search-box" flex="1" type="timed" timeout="500"
oncommand="searchLibrary();"/>
<image id="addLibraryImage" onclick="addLibrary();"
src="../skin/images/addLibrary.gif" />
<image id="collapseAllImage" onclick="collapseAll();"
src="../skin/images/collapseAll.gif" />
</hbox>
•
Library tree. This is the most important element in the main UI. context refers to
a context menu id. The onkeypress value means that, when the ENTER key is
pressed, the node’s URL will open in the current tab.
onclick tells what to do when the mouse is left-clicked. Two other options you can
set are tab, to open in a new tab, and window, to open in a new Firefox instance.
Since the tree is a little complicated, we decided to use a customized tree view, in
which the child elements under the tree are just placeholders (see listing 5). We’ll
render the tree dynamically by programming.
Listing 5. Customized tree view
<tree id="quickrTree" flex="1" class="plain"
context="quickrContextMenu"
onkeypress="if (event.keyCode == 13) openURLIn('current');"
onclick="handleQuickrConClick(event);" hidecolumnpicker="true"
ondraggesture="if (event.originalTarget.localName ==
'treechildren') nsDragAndDrop.startDrag(event, quickrDNDObserver);"
ondragdrop="nsDragAndDrop.drop(event,quickrDNDObserver)"
canDrop="nsDragAndDrop.canDrop(event,quickrDNDObserver);">
<treecols id="quickrTreeCols">
<treecol flex="1" id="Name" persist="sortActive sortDirection"
hideheader="true" primary="true"/>
</treecols>
<treechildren/>
</tree>
You can go to the Mozilla development center to learn more about the XUL tree
and the custom tree view.
•
Context menu. The context menu pops up when you right-click the mouse or as
otherwise defined by Firefox. Pop-up menus are displayed automatically, but
before the menu renders, you can do things like hide certain menu items by setting
the popupshowing attribute to the function you’d like to call (see listing 6).
Listing 6. Context menu example
<popup id="quickrContextMenu" popupshowing="buildContextMenu(event);">
<menuitem id="miOpen" label="&openLinkInWindow.label;"
accesskey="&openLinkInWindow.accesskey;" default="true"
oncommand="openURLIn('current');"/>
…………
…………
<menuseparator id="pre-properties-separator"/>
<menuitem id="miProperties" label="&properties.label;"
accesskey="&properties.accesskey;" oncommand="showProperties();"/>
</popup>
So far we’ve discussed elements the can be displayed in the UI. We also need to tell
Firefox to load locale files and dependent script files such as dojo files:
<script type="application/x-javascript" src="dojo12/dojo/dojo.js"/>
Control module
The control module is a set of functions working in the background of the UI. There
are many language options such as C++, Java, and JavaScript that can be used to
implement the functions; however, JavaScript may be the most convenient.
You don’t need to do any extra compile or other work to deploy your code with
JavaScript, and since it meets our needs, we used it as our implementation language.
Note that most control code is in content/quickrconnector.js.
5.5
Initialize connector
So far we’ve been describing the basic UI components of the connector. Now we
discuss how the connector interacts with the Quickr server.
The initialize function QuickrConnectorCommonInit is set as the page’s onload
attribute value in quickrconnector.xul. The most important thing is reading the config
file to get the list of Quickr document libraries.
Libraries data are stored in the config file as a JSON object. FileIO.js encapsulates the
file read/write operations using Mozilla file IO. When the data is read from the config
file, the content is translated into JavaScript variables so it can be accessed from the
connector:
var filein = FileIO.open(gConfigFilePath);
var data = FileIO.read(filein);
var data = eval(data);
A class, quickrcon.QuickrLib, is introduced to hold the library’s metadata (see listing
7). Setters and getters are ignored here.
Listing 7. Document library metadata
dojo.declare("quickrcon.QuickrLib",null,{
constructor: function(title,url,feedUrl,server,user,password){
this.title = title;
this.url = url;
this.feedUrl = feedUrl;
this.server = server;
this.user = user;
this.password = password;
}
}
The Quickr document library metadata include the library’s name, a view URL to
open the library in a browser, a feed URL to fetch its children folder/document, the
server to which it belongs, and log-on credential information.
After the config file is loaded, the libraries are filled into an array, namely, libs of
quickrcon.QuickrLib objects. Then a data model is built for the tree view, which we
address below in subsection 5.6.3, “Building the data model.”
Note that the Class quickrcon.QuickrLib definition is in the file
content/dojo12/quickrcon/QuickrData.js.
5.6
Tree implementation
The tree adopts a Model-View-Controller (MVC) pattern. Let’s look at the tree view
interface to see what the model should be.
5.6.1 Tree view
The tree view is the interface called by the tree object to render the tree. gTreeView
implements this interface. Table 2 is excerpted from the nsITreeView page and shows
the methods and attributes we should implement in order for the tree view of Quickr
content to be rendered properly. The methods are described in more detail later in this
section.
Table 2. Method overview
void getRowProperties(in long index, in nsISupportsArray properties);
void getCellProperties(in long row, in nsITreeColumn col, in
nsISupportsArray properties);
void getColumnProperties(in nsITreeColumn col, in nsISupportsArray
properties);
boolean isContainer(in long index);
boolean isContainerOpen(in long index);
boolean isContainerEmpty(in long index);
boolean isSeparator(in long index);
boolean isSorted();
boolean canDrop(in long index, in long orientation);
void drop(in long row, in long orientation);
long getParentIndex(in long rowIndex);
boolean hasNextSibling(in long rowIndex, in long afterIndex);
long getLevel(in long index);
AString getImageSrc(in long row, in nsITreeColumn col);
long getProgressMode(in long row, in nsITreeColumn col);
AString getCellValue(in long row, in nsITreeColumn col);
AString getCellText(in long row, in nsITreeColumn col);
void setTree(in nsITreeBoxObject tree);
void toggleOpenState(in long index);
void cycleHeader(in nsITreeColumn col);
void selectionChanged();
void cycleCell(in long row, in nsITreeColumn col);
boolean isEditable(in long row, in nsITreeColumn col);
boolean isSelectable(in long row, in nsITreeColumn col);
void setCellValue(in long row, in nsITreeColumn col, in AString value);
void setCellText(in long row, in nsITreeColumn col, in AString value);
void performAction(in wstring action);
void performActionOnRow(in wstring action, in long row);
void performActionOnCell(in wstring action, in long row, in
nsITreeColumn col);
Attributes:
Attribute
Type
rowCount long
selection
nsITreeSelection
Description
Readonly: The total number of rows in the tree
(including the offscreen rows).
The selection for this view.
5.6.2 Tree model analysis
The following methods and attributes are useful for data model analysis:
•
•
•
•
•
rowCount: Returns how many nodes the tree has, including all the server,
library, folder, and document nodes.
isContainer(): Returns whether the node can contain child nodes. There are
container nodes like folder nodes and non-container nodes like document
nodes in the data model.
getLevel(): Returns the node’s level, which is used to determine how much it’s
indented when rendering
getCellText(): Returns the node’s label.
getImageSrc(): Returns the image to be used to represent the node.
Listing 8 defines a generic tree node, ignoring the setters and getters:
Listing 8. Generic tree node
dojo.declare("quickrcon.TreeNode",null,{
constructor: function(lib,title,nodeType,url,entry,parent,level){
this.lib = lib;
this.title = title;
this.url = url;
this.nodeType = nodeType;
this.parent = parent;
this.entry = entry;
this.level = level == null? 0 : level;
this.imageSrc = null;
}
}
There are four types of tree nodes:
quickrcon.TreeNode.DOCUMENT = "document";
quickrcon.TreeNode.FOLDER = "folder";
quickrcon.TreeNode.LIBRARY = "library";
quickrcon.TreeNode.SERVER = "server";
Figure 4 shows the design of the tree model class, in which the folder and the library
have almost the same properties and methods, and they both can be a FolderNode
instance.
ServerNode has a few more properties than FolderNode because it holds the user’s
name and password on the server. ServerNode is also the root node of the tree, which
means its level is zero.
Figure 4. Tree model class
quickrcon.TreeNode
quickrcon.DocumentNode
quickrcon.FolderNode
quickrcon.ServerNode
Note that all the class definitions are in content/dojo12/quickrcon/Tree.js.
5.6.3 Building the data model
There are only libraries entries in the config file, but servers can be calculated by
traversing the libraries. The corresponding function is getAllServerNodes, which
builds a map with the server URL as the key and an array of libraries on the server as
the value.
The data model is a “forest,” in data structure terminology. The root nodes are server
nodes, the second-level children are library nodes, and the lower-level nodes are
folder or document nodes.
The gDataModel is constructed after the connector is initialized, a forest is built, and
there are just two levels, the server nodes and library nodes (see listing 9).
Listing 9. gDataModel
gDataModel = new Array();
for(var i in serverNodesMap.keys){
var server = serverNodesMap.keys[i];
var nodes = serverNodesMap.getServerNodes(server).nodes;
var serverNode = new
quickrcon.ServerNode(null,server,quickrcon.TreeNode.SERVER,null);
serverNode.setLevel(0);
serverNode.setChildren(new Array());
serverNode.setUser(serverNodesMap.getServerNodes(server).user);
serverNode.setPassword(serverNodesMap.getServerNodes(server).password);
gDataModel.push(serverNode);
for(var j = 0; j < nodes.length; j++){
var node = nodes[j];
serverNode.getChildren().push(node);
node.setParent(serverNode);
}
}
The data model is enriched when you click on a library or folder, which leads to fetch
feed/entry from a remote server.
5.6.4 Updating the tree view
As mentioned above, the tree view needs an array to store the tree nodes so that the
row index can be used to fetch the node data. So we need preorder traversal of the
data model, which can be done by a recursive call of buildTreeData function (see
listing 10).
Listing 10. buildTreeData function
gTreeData = new Array();
var buildTreeData = function(node){
if(node == null) return;
gTreeData.push(node);
if(node.isContainer() && node.getOpen() && node.getChildren()){
for(var i = 0; i < node.getChildren().length; i++){
buildTreeData(node.getChildren()[i]);
}
}
};
When gTreeData is ready, we update rowCount of gTreeView and refresh the tree view.
Updating the tree view is encapsulated in the updateTreeView method.
5.6.5 Consume REST services
Quickr provides REST services, following the Atom specification. We use IBM’s dojo
Atom extension—contributed to the dojo open source community in version 1.3—to
simplify the handling of Atom service requests/responses. The code snippet in listing
11 demonstrates how to use it.
Listing 11. dojo Atom extension in use
function getChildrenData(node,preventCache){
var handle = new FeedHandler();
handle.currentNode = node;
var atomIO = new ibm_atom.io.atom.AtomIO();
atomIO.user = node.getLib().getUser();
atomIO.password = node.getLib().getPassword();
var url = null;
if(node.getNodeType() == quickrcon.TreeNode.LIBRARY
|| node.getNodeType() == quickrcon.TreeNode.FOLDER){
url = node.getFeedUrl();
if(url == null)
return;
url += "?pagesize=10000&pageSize=10000";
node.setStatus("waiting");
searchLibrary();
atomIO.getFeed(url, dojo.hitch(handle,"handleFeed"),
function(err){node.setStatus("done");alert(err);});
}
}
Quickr libraries feed service returns 10 entries by default, as do FileNet® and Content
Manager content services. Since we’d like to return all the entries in one request, in
the above code we add a pagesize parameter with a large value (10000). Note that the
page size parameter for the Content Manager server is pageSize. We can add both
pagesize and pageSize, to support all the servers. Also, note the following:
•
•
•
node.setStatus("waiting") tells the tree view to set a loading image for the
node the next time the tree view is updated.
searchLibrary filters out libraries to be displayed and updates the tree view.
getFeed uses dojo.xhr calls REST services. The three parameters of this
function are the service URL, the callback when the response is correct, and
the error callback when an error occurs.
The FeedHandler is a wrapper of the handleFeed function (see listing 12). When the
service response is correct, the feed handler parses the response Atom document and
create folder/document nodes, integrate them into the data model, change the parent
node’s status to done and, finally, call searchLibrary to update tree view.
Listing 12. Feedhandler
var FeedHandler = function(){
this.handleFeed = function (feed, ioArgs){
var cnode = this.currentNode;
cnode.setOpen(true);
cnode.setStatus("done");
var entries = feed.entries;
if (entries != null) {
cnode.children = new Array();
for(var i = 0; i < entries.length; i++){
var entry = entries[i];
try{
var title = entry.title.value;
var category = entry.getCategories()[0];
var type = category.term.value;
var url = null;
if(entry.links){
for(var j = 0; j < entry.links.length; j++){
var link = entry.links[j];
if(link.rel && link.rel.value == "alternate"){
url = link.href.value;
break;
}
}
}
var node = null;
if(type == quickrcon.TreeNode.FOLDER){
node = new quickrcon.FolderNode( cnode.getLib(),
title,quickrcon.TreeNode.FOLDER, url, entry,cnode,
cnode.getLevel() + 1,null,false);
}
else if(type == quickrcon.TreeNode.DOCUMENT){
node = new quickrcon.DocumentNode(cnode.getLib(),
title, quickrcon.TreeNode.DOCUMENT, url, entry,
cnode, cnode.getLevel() + 1);
}
if(node != null)
cnode.getChildren().push(node);
}catch(e){}
}
cnode.getChildren().sort(function(a,b){
if(a.getNodeType() != b.getNodeType())
return a.getNodeType() > b.getNodeType() ? 1 : -1;
else
return a.getTitle().toLowerCase() >
b.getTitle().toLowerCase() ? 1 : -1;
});
}
searchLibrary();
};
};
Build context menu
There are 13 menu items in total, but not all of them are shown at one time. The
buildContextMenu function decides which items should be displayed in the context
menu pop-up. First it checks whether there is a selected node. If there’s not, then only
the add library item can be displayed; if there is, it will check the node type and
decide what item should appear.
5.6.6 Operation functions
Almost all the connector functions are triggered by menu items. When a menu item is
selected, the following corresponding functions are called:
•
addLibrary. Prepares the parameter for the Add Library dialog box and calls
window.openDialog to open that dialog. When the OK button of this dialog box is
clicked, the callback is called to save the added library to the config file and to
update the data model and tree view:
var params =
{atomIO:atomIO,callback:callback,servers:gDataModel,out:null};
window.openDialog("addLibrary.xul", "", "chrome, dialog, centerscreen,
resizable=yes", params).focus();
•
renameLibrary. Renames a library. This operation can change only local data
(meaning it does not rename the actual Document Library on the server).
•
deleteLibrary. Deletes a library in the tree view and config file. This operation can
change only local data. (meaning it does not delete the actual Document Library
on the server).
•
collapseAll. Collapses all the tree nodes by setting all the nodes’ open state to
false and then updating tree view.
•
collapseExpand. Collapses or expands a tree node. If a node is already open, then
it collapses it. If it’s collapsed, you should check whether the child data has been
fetched; if not, then call service should be called to load data first.
•
openURLIn. Opens a URL in a specific place, either in the current tab, a new tab,
or in a new window. If there is an event object such as a click event, the function
whereToOpenLink can be used to determine the place to open.
•
refresh. Refreshes the current node’s child data, and will call the REST service
and rebuild the child nodes.
•
quickrAddBookmarks. Adds the current node’s view URL to bookmarks via the
Firefox programming interface. In Firefox 3, it looks like this:
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = ios.newURI(url, null, null);
PlacesUIUtils.showMinimalAddBookmarkUI(uri,title);
•
quickrCopyLink. Copies the current node’s view URL to the clipboard:
var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
.getService(Components.interfaces.nsIClipboardHelper );
clipboard.copyString(url);
•
mailto. Sends the current node link to a recipient. The easiest way is by using the
mailto protocol; you just need to prepare the email’s subject and body content as a
string, and then combine them into a mail URL and open it (see listing 13).
Listing 13. mailto example
var url = node.getUrl();
var title = node.getTitle();
var htmlString = "<A HREF='" + url + "'>" + title + "</A>";
var mailUrl = 'mailto:?subject=' + escape(title) + '&body=' +
escape(htmlString);
var tab = openUILinkIn(mailUrl,"tab");
•
downloadDocument. Downloads a document. It applies only to a document node,
and can be done by opening its download URL.
•
showProperties. Shows a folder or a document’s metadata. These data are stored
in an entry that comes from the parent’s feed service. A simple XUL dialog
propertyDialog.xul file is also created to show these properties. Refer to this file
for more details.
5.6.7 Adding libraries to a connector
For a user to add a document library to the list shown by this connector, there are two
steps involved.. First, the user must enter the server information in the Add Library
dialog box and click Next (see figure 5).
Figure 5. Input server information
At this point, the document feed service http://host:port/dm/atom/libraries is called to
get all the libraries that the server hosts, after which a library treeview will display as
shown in figure 6.
Figure 6. Select libraries
All the XUL elements in this view are defined in addLibrary.xul. When the dialog is
launched, the initialize function addLibraryInit filters out the elements to display from
the first step. When the user clicks the Next button, doNext is called to hide some
elements and display others. To hide or display an element, the hide attribute is set to
true or false.
When the user clicks the Save button, doOK is called to prepare data and call the
callback function to save the list of libraries locally.
6. Conclusion
Lotus Quickr provides rich and powerful REST/SOAP services to customize the
functions of servers. This article has demonstrated how to use Quickr document REST
services to build a customized Firefox connector. Through these programming
interfaces you can build your own Quickr connectors easily and quickly.
7. Resources
•
developerWorks Lotus Quickr product page:
http://www.ibm.com/developerworks/lotus/products/quickr/?S_TACT=105AGX1
3&S_CMP=LP
•
Lotus Quickr application programming interfaces:
http://www-10.lotus.com/ldd/lqwiki.nsf/dx/documents-services
•
Lotus Quickr Enablement Materials:
http://www-10.lotus.com/ldd/lqwiki.nsf/dx/ibm-lotus-quickr-technical-enablement
-materials-for-business-partners
•
Lotus Quickr documentation page:
http://www.ibm.com/developerworks/lotus/documentation/quickr/
•
Mozilla Developer Center, Main page:
https://developer.mozilla.org/En
•
Dojo Toolkit:
http://www.dojotoolkit.org
8. About the authors
Shun Zhang is a software engineer for IBM in Beijing, with a focus on Lotus Quickr,
and Web 2.0 and SOA technologies. You can reach him at [email protected].
Hui Jian He is a staff software engineer for IBM in Beijing, focusing on Lotus Quickr
from its first release. Before that he worked on IBM Workplace Collaboration
Services, WebSphere Portal, and Workplace Services Express products. You can reach
him at [email protected].
Acknowledgement
The authors would like to thank Greg Melahn for his valuable assistance in technically
reviewing this paper.
Trademarks
•
•
•
•
developerWorks, FileNet, IBM, Lotus, Notes, Quickr, Sametime, and Symphony are
trademarks or registered trademarks of IBM Corporation in the United States, other
countries, or both.
Microsoft and Windows are registered trademarks of Microsoft Corporation in the United
States, other countries, or both.
Java and all Java-based trademarks and logos are trademarks or registered trademarks of
Sun Microsystems, Inc. in the United States, other countries, or both.
Other company, product, and service names may be trademarks or service marks of
others.
Fly UP