"The problem's all inside your code," she said to me
"The answer is easy if you take it logically
I'd like to help you in your struggle to be free
There must be fifty ways to leave your bookmark...â
Fifty ways to leave your bookmark was an experiment in social authoring and a challenge to see whether a developerWorks® article could be generated in a fixed time frame. The experiment and the article were explained and kicked off with an email to potential participants:
Fifty Ways to Leave Your Bookmark - You are invited to participate!
The ultimate goal of this experiment is to have a group of people contribute the content for a developerWorks article, in the span of one day, that shows how to use Atom Publishing Protocol (AtomPub) from as many programming languages as possible. To build on the momentum of several articles about the Lotus Connections API, we'll use Dogear as our AtomPub-enabled service.
Anyone and everyone who would like to join the effort is welcome â everyone who contributes will be recognized as a co-author.
We'll take entries at any time that it's Friday, 10 Aug 2007 somewhere in the world. So accounting (roughly) for some zigs and zags in the International Date Line and for Daylight Saving time, letâs say from midnight in Kiritimati (6:00am EDT, Thursday, 10 Aug) to midnight in Honolulu (6:00am EDT, Saturday, 12 Aug).
If you'd like to contribute an example to the article, go to the Fifty ways to leave your bookmark wiki, review the instructions, and add your example.
Weâre looking for examples in languages such as Ruby, PHP, Java, Python, Flash ActionScript, C#, LotusScript, and JavaScript. But we'll also want to show how versatile a service that exposes an APP API can be. If you can pull it off in APL, COBOL, PL/1, PostScript, or another language , go ahead.
We used an internal wiki for collecting everyoneâs submissions and for posting the instructions for the authors. The overview instructions were as follows:
You (the contributing author) will stake your claim to cover a language by adding a new wiki page, starting from 10 (adding 1 for each additional language) and noting the name of the language, for example, â10 - Java.â Follow the format that shows how to post the bookmark in the language you have chosen. You can choose as many languages as you like; just put each one on a separate page.
The authors also needed to know what specifically they would have to code to show an example AtomPub call on the Dogear server, so they were given these instructions as well:
Weâll be making the same call in each language. We'll programmatically bookmark the Lotus Connections home page (http://ibm.com/lotus/connections), tag it with "lotus," "connections," and "50WaysToLeaveYourBookmark," set the description to "I posted this from <language>" and the title to "The Lotus Connections Page."
Since an AtomPub call is really just an HTTP call, here is the raw format of the data that we'll be passing to the server:
POST /dogear/api/app?email=user@company.com HTTP/1.1 Host: www.company.com Content-Type: application/atom+xml Authorization: Basic RG9uIFA1aXhvdAAAAm9jaW5hAARl <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <author><name>Author</name></author> <title>The Lotus Connections Page</title> <content type="html"><![CDATA[I posed this from <language>]]> </content> <category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="bookmark" /> <category term="lotus" /> <category term="connections" /> <category term="50WaysToLeaveYourBookmark" /> <link href="http://www.ibm.com/lotus/connections" /> </entry> |
With that, the challenge was set forward. Each author selected a programming language and wrote an example that posts a bookmark on a running Dogear server. They posted the same link, with a mention of the language from which it was posted, in the bookmark's description (see figure 1).
Figure 1. Example bookmark description

After the day was finished, we had fewer entries than we would have liked, so we extended the deadline until the following week.
All the examples that follow in this article represent language-specific ways to make this call.
For more details about the Dogear API and the AtomPub protocol, refer to the developerWorks article, âDeploying IBM Lotus Connections: Integrating with other systems.â
What follows are the 17 samples collected over the designated period during which authors had to submit their samples. Each sample contains the language used, any libraries that were relied on, any comments by the author, and, of course, the code itself.
The examples below work with Dogear 1.0.x and are a good starting point for accessing data in the other Lotus Connections services. Please note, however, that the Lotus Connections Activities 1.0.2 API requires that you set the user-agent field in your requests.
Java
by James Snell (via snellspace.com)
Apache Abdera - Atom parsing and generation
Abdera abdera = new Abdera();
Client client = new CommonsClient(abdera);
client.addCredentials("http://dogear.tap.ibm.com/api/app", null, null, new
UsernamePasswordCredentials("userid","password"));
ClientResponse resp = client.get("http://dogear.tap.ibm.com/api/app");
Document<Service> service_doc = resp.getDocument();
Service service = service_doc.getRoot();
Collection collection = service.getCollection("My Bookmarks", "Entries");
String coll_uri = collection.getResolvedHref().toASCIIString();
Entry entry = abdera.newEntry();
entry.setId(""); //ignored by the server, required by APP
entry.addAuthor("james"); //ignored by the server, required by APP
entry.addLink("http://ibm.com/lotus/connections"); // the url being bookmarked
entry.setTitle("The Lotus Connections Page");
entry.setContentAsHtml("I posted this from Java");
entry.addCategory("lotus");
entry.addCategory("connections");
entry.addCategory("50WaysToLeaveYourBookmark");
// optional in dogear
entry.addCategory("http://www.ibm.com/xmlns/prod/sn/type","bookmark",null);
resp = client.post(coll_uri, entry);
switch(resp.getType()) {
case SUCCESS:
String location = resp.getLocation().toASCIIString();
System.out.println("New entry created at: " + location);
break;
default:
System.out.println("Error: " + resp.getStatusText());
}
|
None
import java.net.*;
import java.io.*;
import javax.net.ssl.*;
import javax.net.*;
/* Bare metal Java version! */
public class Bookmark {
public static void main(String[] args) throws Exception {
SocketFactory factory = SSLSocketFactory.getDefault();
Socket socket = factory.createSocket("dogear.tap.ibm.com", 443);
OutputStreamWriter out =
new OutputStreamWriter(socket.getOutputStream(), "UTF8");
out.write("POST /api/app?email=dgriff@uk.ibm.com HTTP/1.1\r\n");
out.write("Host: www.ibm.com\r\n");
String encoding =
new sun.misc.BASE64Encoder().encode("dgriff@uk.ibm.com:password".getBytes());
out.write("Authorization: Basic " + encoding + "\r\n");
String data = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
"<entry xmlns=\"http://www.w3.org/2005/Atom\">\r\n" +
"<author><name>Author</name></author>\r\n" +
"<title>The Lotus Connections Page</title>\r\n" +
"<content type=
\"html\"><![CDATA[I posted this from Java]]></content>\r\n" +
"<category scheme=\"http://www.ibm.com/xmlns/prod/sn/type\"
term=\"bookmark\" />\r\n" +
"<category term=\"lotus\" />\r\n" +
"<category term=\"connections\" />\r\n" +
"<category term=\"50WaysToLeaveYourBookmark\" />\r\n" +
"<link href=\"http://www.ibm.com/lotus/connections\" />\r\n" +
"</entry>\r\n";
out.write("Content-Length: " + data.length() + "\r\n");
out.write("Content-Type: application/atom+xml\r\n");
out.write("\r\n");
out.write(data);
out.flush();
BufferedReader in =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
}
|
PHP with cURL and xmlwriter
by Caroline Maynard
There are many ways to do this with PHP. For the purposes of this article, letâs look at a straightforward use of cURL using PHP.
The code looks longer than some examples because the XML was created programmatically through a general-purpose "create a dogear bookmark" function. If you prefer, you could reduce this to a couple of lines to include canned XML from a file or by use of a heredoc.
It was found that the CURLOPT_SSL_VERIFYPEER setting was needed to avoid the following error:
âGot 60 : SSL certificate problem, verify that the CA cert is OK.
Details: error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.â
PHP 5.1.x with the built-in extensions for cURL and xmlwriter.
<?php
try {
$target = "https://dogear.tap.ibm.com/api/app/?email=caroline.maynard%40uk.ibm.com";
$user = "caroline.maynard@uk.ibm.com";
$passwd = "<password>";
$xml = create_entry_xmlwriter();
$headers = array("Content-Type: application/atom+xml ");
$handle = curl_init($target);
$curlopt_array = array(
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $xml,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERPWD => $user.':'.$passwd,
CURLOPT_FOLLOWLOCATION => true);
curl_setopt_array($handle, $curlopt_array);
$result = curl_exec($handle);
if ($result === false) {
print "Got " . curl_errno($handle) . " : " . curl_error($handle) . "\n";
curl_close ($handle);
return;
}
$response_http_code = curl_getinfo ($handle, CURLINFO_HTTP_CODE);
if ($response_http_code != 201) {
print("HTTP status code: $response_http_code \n");
curl_close($handle);
return;
}
curl_close($handle);
} catch (Exception $e) {
print $e;
}
function create_entry_xmlwriter($author = "Caroline Maynard",
$title = "The Lotus Connections Page",
$link = "http://www.ibm.com/lotus/connections",
$categories = array('lotus', 'connections', '50WaysToLeaveYourBookmark')) {
$xmlwriter = new XMLWriter();
$xmlwriter->openMemory();
$xmlwriter->startDocument("1.0", "UTF-8");
$xmlwriter->startElement('entry');
$xmlwriter->writeAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$xmlwriter->startElement('author');
$xmlwriter->writeElement('name', $author);
$xmlwriter->endElement();
$xmlwriter->writeElement('title', $title);
$xmlwriter->startElement('link');
$xmlwriter->writeAttribute('href', $link);
$xmlwriter->endElement();
$xmlwriter->startElement('content');
$xmlwriter->writeAttribute('type', 'html');
$xmlwriter->text('I posted this from PHP');
$xmlwriter->endElement();
$xmlwriter->startElement('category');
$xmlwriter->writeAttribute('term', 'bookmark');
$xmlwriter->writeAttribute('scheme', 'http://www.ibm.com/xmlns/prod/sn/type');
$xmlwriter->endElement();
if ($categories) {
$categories = (array)$categories;
foreach ($categories as $category) {
$xmlwriter->startElement('category');
$xmlwriter->writeAttribute('term', $category);
$xmlwriter->endElement();
}
}
$xmlwriter->endElement();
$xmlwriter->endDocument();
return $xmlwriter->outputMemory();
}
?>
|
#!/usr/bin/ruby
require 'rexml/document'
require 'rexml/cdata'
require 'net/http'
require 'net/https'
require 'uri'
user = 'user@example.com'
password = 'password'
url = URI.parse('https://dogear.tap.ibm.com:443/api/app')
# Create the XML document
doc = REXML::Document.new('<entry xmlns="http://w3.org/2005/Atom"/>')
r = doc.root
r.add_element('author').add_element('name').text = 'Sacha Chua'
r.add_element('title').text = 'The Lotus Connections Page'
content = r.add_element 'content', { 'type' => 'html' }
content.text = REXML::CData.new('I posted this from Ruby')
r.add_element('category',
{ 'term' => 'bookmark',
'scheme' => 'http://www.ibm.com/xmlns/prod/sn/type' })
r.add_element 'category', { 'term' => 'lotus' }
r.add_element 'category', { 'term' => 'connections' }
r.add_element 'category', { 'term' => '50WaysToLeaveYourBookmark' }
r.add_element 'link', { 'href' => 'http://www.ibm.com/lotus/connections' }
doc.add(REXML::XMLDecl.new('1.0', 'UTF-8'))
http = Net::HTTP.new(url.host, url.port)
# Post the document
req = Net::HTTP::Post.new(url.path + '?email=' + user)
req.basic_auth user, password
req['Content-Type'] = 'application/atom+xml'
req.body = doc.to_s
http.use_ssl = true
http.start do |http|
response = http.request(req)
case response
when Net::HTTPSuccess
puts "Posted!" + response.body
else
response.error!
end
end
|
None
//Construct a standard XMLHttpRequest Object for Mozilla Firefox or Internet Explorer
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request) {
alert("Error initializing XMLHttpRequest!");
}
//Construct the XML to be sent in the request as a string
//The string is split and concatenated here for clarity.
var postXML = '<?xml version="1.0" encoding="utf-8"?>'
+'<entry xmlns="http://www.w3.org/2005/Atom">'
+'<author><name>Author</name></author>'
+'<title>The Lotus Connections Page</title>'
+'<content type="html">I posted this from JavaScript</content>'
+'<category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="bookmark" />'
+'<category term="lotus" />'
+'<category term="connections" />'
+'<category term="50WaysToLeaveYourBookmark" />'
+'<link href="http://www.ibm.com/lotus/connections" />'
+'</entry>';
var postURL = "http://www.company.com/dogear/api/app";
request.open("POST",postURL,true,"userid","password");
request.setRequestHeader("Content-type", "application/atom+xml");
request.setRequestHeader("Content-length", postXML.length);
request.setRequestHeader("Connection", "close");
request.onreadystatechange = postResponse;
request.send(postXML);
function postResponse() {
//Check for success: HTTP 201 - Created
if (request.readyState == 4) {
if(request.status == 201) {
//Activity successfully created
//Do any post-processing here...
} else {
alert("Error: " + request.status + " - " + request.statusText);
//Further error processing...
}
}
}
|
XML::Generator - XML Generator
LWP::UserAgent - Library for WWW in Perl
require LWP::UserAgent;
use LWP::Debug qw(+ -conns);
my $user = "axel_magard\@de.ibm.com";
my $pw = "xxxxxxxx";
my $server = "dogear.tap.ibm.com";
my $url = "http://".$server."/api/app";
my $port = "443";
# Create a user object ...
my $ua = LWP::UserAgent->new;
$ua->agent("MyBookmark/0.1 ");
$ua->credentials($server.':'.$port, 'Dogear', $user, $pw );
push @{ $ua->requests_redirectable }, 'POST'; # Avoid the 302 return code
# Create a request ...
my $req = HTTP::Request->new(POST => $url);
use XML::Generator ':pretty';
# Build XML document ...
my $gen = XML::Generator->new(':pretty',
namespace => ["http://www.w3.org/2005/Atom"]);
$content = sprintf $gen->xml($gen->entry( $gen->author("Axel Magard"),
$gen->title("The Lotus Connections Page"),
$gen->content({type => 'html'},"I posted this from Perl."),
$gen->category({scheme => "http://www.ibm.com/xmlns/prod/sn/type",
term => "bookmark"}),
$gen->category({term=>"lotus"}),
$gen->category({term=>"connections"}),
$gen->category({term=>"50WaysToLeaveYourBookmark"}),
$gen->link({href=>"http://www.ibm.com/lotus/connections"})
)
);
# Set request content
$req->content_type('application/atom+xml');
$req->content($content);
# Pass request to the user agent and get a response back
my $res = $ua->request($req);
# Check the outcome of the response
if ($res->is_success) {
print "Bookmark posted.\n";
}
else {
print $res->status_line, "\n";
}
|
None
var xmlString = '<?xml version="1.0" encoding="utf-8"?>'
+'<entry xmlns="http://www.w3.org/2005/Atom">'
+'<author><name>Author</name></author>'
+'<title>The Lotus Connections Page</title>'
+'<content type="html"><\!\[CDATA\[I posed this from
ActionScript\]\]></content>'
+'<category scheme="http://www.ibm.com/xmlns/prod/sn/type"
term="bookmark" />'
+'<category term="lotus" />'
+'<category term="connections" />'
+'<category term="50WaysToLeaveYourBookmark" />'
+'<link href="http://www.ibm.com/lotus/connections" />'
+'</entry>';
// create new xml object from xml string
var xml:XML = new XML(xmlString);
// set content type
xml.contentType = "application/atom+xml";
// send to server and show result in new browser window
xml.send("https://dogear.tap.ibm.com/api/app", "_blank");
|
Shell script / command line
by Andy Piper (http://andypiper.co.uk )
cURL - a command line tool for HTTP
It is possible to invoke the APP API from various shell scripting environments by posting a file with the correct Atom XML format using cURL.
curl -u "andy.piper@uk.ibm.com:passw0rd" -X POST -H 'Content-Type:application/atom+xml'
--data-binary @atomfile.xml https://dogear.tap.ibm.com/api/app?
email=andy.piper@uk.ibm.com
|
Through shell using wget
by Brian Olore (bolore@us.ibm.com)
wget - GNU Wget is a free software package for retrieving files using HTTP, HTTPS and FTP, the most widely-used Internet protocols.
Create a bookmark - wget
wget --header="Content-type: application/atom+xml" --post-file=content.txt
--http-user=bolore@us.ibm.com --http-password=passw0rd
"https://dogear.tap.ibm.com/api/app?email=bolore@us.ibm.com"
|
Message Broker and ESQL
by Jeff Lowrey
Use a basic Compute Node, with ComputeMode set to Message And Local Environment. Connect this Compute Node to an HTTPRequest node. You'll need to set the URL on the HTTPRequest node to something - it doesn't really matter what. You'll also need to put in some kind of an Input node to start the flow. I used an MQInput node, but it doesn't matter. One could ideally create user and password as UserDefinedProperties, so that they would be set by the admin at deployment time.
DECLARE user CHARACTER; DECLARE password CHARACTER; CALL CopyMessageHeaders(); -- CALL CopyEntireMessage(); SET user = 'user'; SET password = 'password'; SET OutputRoot.MQMD = NULL; SET OutputRoot.Properties.MessageDomain = 'XMLNS'; -- set the HTTP destination URL, and various HTTP headers -- these will be used by the HTTPRequest node SET OutputLocalEnvironment.Destination.HTTP.RequestURL = 'https://dogear.tap.ibm.com/api/app?email='||user; SET OutputRoot.HTTPRequestHeader."Content-Type"= 'application/atom+xml'; SET OutputRoot.HTTPRequestHeader."Authorization" = 'Basic '||b64Encode(CAST(user||': '||password as BLOB CCSID InputRoot.Properties.CodedCharSetId)); -- create the message body which contains the Atom -- format XML required to create the bookmark SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.(XMLNSC.Attribute)Version = '1.0'; SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.(XMLNSC.Attribute)Encoding = 'UTF-8'; SET OutputRoot.XMLNSC.entry.author.name='Jeff Lowrey'; SET OutputRoot.XMLNSC.entry.(XMLNSC.NamespaceDecl)xmlns:xmlns = 'http://www.w3.org/2005/Atom'; DECLARE outRef REFERENCE TO OutputRoot.XMLNSC.entry; SET outRef.title='The Lotus Connections Page'; SET outRef.(XMLNSC.CDataField)content = 'I posted this from Message Broker using ESQL'; SET outRef.content.(XMLNSC.Attribute)"type" = 'html'; SET outRef.category[1].(XMLNSC.Attribute)"scheme" = 'http://www.ibm.com/xmlns/prod/sn/type'; SET outRef.category[1].(XMLNSC.Attribute)"term" = 'bookmark'; SET outRef.category[2].(XMLNSC.Attribute)"term" = 'lotus'; SET outRef.category[3].(XMLNSC.Attribute)"term" = 'connections'; SET outRef.category[4].(XMLNSC.Attribute)"term" = '50WaysToLeaveYourBookmark'; SET outRef.link.(XMLNSC.Attribute)"href"='http://www.ibm.com/lotus/connections'; |
There's an additional declaration needed, in the ESQL file but outside the Compute module. It allows you to leverage a built-in base64 encoding routine, which is used in setting up the HTTP Basic Auth values in the header.
CREATE PROCEDURE b64Encode(IN source BLOB) RETURNS CHARACTER LANGUAGE JAVA EXTERNAL NAME "com.ibm.broker.javacompute.Base64.encode"; |
AppleScript
by Andy Piper (http://andypiper.co.uk)
cURL - a command line tool for HTTP (which happens to be built in to OS X)
XML Tools Scripting Addition - extension for building XML in AppleScript
set outputfile to (((path to desktop) as string) & "atomentry.xml")
as file specification
set atomfile to POSIX path of outputfile as text
-- NB the XML tools extension does not support CDATA so the content is
typed "text" rather than "html"
-- also can't use an attribute named 'scheme' as it seems to get generated strangely
set theXML to
{class:XML element, XML tag:"entry",
XML attributes:{xmlns:"http://www.w3.org/2005/Atom"}, XML contents:{
{class:XML element, XML tag:"author", XML contents:
{class:XML element, XML tag:"name", XML contents:{
"Author"}}},
{class:XML element, XML tag:"title", XML contents:{"The Lotus
Connections Page"}},
{class:XML element, XML tag:"content", XML attributes:{type:"text"},
XML contents:{"I posted this from Applescript"}},
{class:XML element, XML tag:"category", XML attributes:{term:"bookmark"}},
{class:XML element, XML tag:"category", XML attributes:{term:"lotus"}},
{class:XML element, XML tag:"category", XML attributes:{term:"connections"}},
{class:XML element, XML tag:"category", XML
attributes:{term:"50WaysToLeaveYourBookmark"}},
{class:XML element, XML tag:"link", XML
attributes:{href:"http://www.ibm.com/lotus/connections"}}}}
generate XML theXML saving as (outputfile) with generating UTF8
set results to do shell script "curl --user 'andy.piper@uk.ibm.com:passw0rd' -X
POST -H 'Content-Type:application/atom+xml' --data-binary @" & atomfile &
"https://dogear.tap.ibm.com/api/app?email=andy.piper@uk.ibm.com"
if results = "" then
set results to "Successfully published the bookmark"
end if
display dialog results buttons "OK"
-- delete the generated Atom XML file to clean up
tell application "Finder"
delete file outputfile
end tell
|
ColdFusion 8.0
by Suzanne Minassian
<cfxml variable="postMe"> <?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <author><name>Author</name></author> <title>The Lotus Connections Page</title> <content type="html"><![CDATA[I posted this from ColdFusion]]></content> <category scheme="http://www.ibm.com/xmlns/prod/sn/type" term="bookmark" /> <category term="lotus" /> <category term="connections" /> <category term="50WaysToLeaveYourBookmark" /> <link href="http://www.ibm.com/lotus/connections" /> </entry> </cfxml> <cfhttp method="POST" url="https://dogear.tap.ibm.com/api/app/?email=minassian@us.ibm.com" username="minassian@us.ibm.com" password="myPasswordHere"> <cfhttpparam type = "XML" value = "#postMe#"> </cfhttp> |
Microsoft® .NET Framework 2.0
Module Module1
Sub Main()
Dim mymemstream As New System.IO.MemoryStream()
Dim mystreamwriter As New System.IO.StreamWriter(mymemstream)
Dim mywriter As New System.Xml.XmlTextWriter(mystreamwriter)
mywriter.WriteStartDocument()
mywriter.WriteStartElement("entry", "")
mywriter.WriteAttributeString("xmlns", "http://www.w3.org/2005/Atom")
mywriter.WriteStartElement("author")
mywriter.WriteElementString("name", "Ben Rubinger")
mywriter.WriteEndElement()
mywriter.WriteElementString("title", "The Lotus Connections Page")
mywriter.WriteStartElement("content", "")
mywriter.WriteAttributeString("type", "html")
mywriter.WriteValue("I posted this from VB.NET")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category", "")
mywriter.WriteAttributeString("scheme", "http://www.ibm.com/xmlns/prod/sn/type")
mywriter.WriteAttributeString("term", "bookmark")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category")
mywriter.WriteAttributeString("term", "lotus")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category")
mywriter.WriteAttributeString("term", "connections")
mywriter.WriteEndElement()
mywriter.WriteStartElement("category")
mywriter.WriteAttributeString("term", "50WaysToLeaveYourBookmark")
mywriter.WriteEndElement()
mywriter.WriteStartElement("link", "")
mywriter.WriteAttributeString("href", "http://www.ibm.com/lotus/connections")
mywriter.WriteEndElement()
mywriter.WriteEndElement()
mywriter.WriteEndDocument()
mywriter.Flush()
Dim myrequest As System.Net.HttpWebRequest =
System.Net.WebRequest.Create
("http://dogear.tap.ibm.com/api/app?email=rubinger@us.ibm.com")
myrequest.Method = "POST"
Dim mycredentials As New System.Net.NetworkCredential
("rubinger@us.ibm.com", "********")
myrequest.Credentials = mycredentials
myrequest.ContentType = "application/atom+xml"
myrequest.ContentLength = mymemstream.Length
Dim poststream As IO.Stream
Try
poststream = myrequest.GetRequestStream()
poststream.Write(mymemstream.GetBuffer(), 0, mymemstream.Length)
Catch ex As Exception
Finally
If Not poststream Is Nothing Then poststream.Close()
End Try
mywriter.Close()
End Sub
End Module
|
Microsoft .NET Framework
using System;
using System.Net;
using System.IO;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
WebResponse webResponse = null;
NetworkCredential credentials = new NetworkCredential();
credentials.UserName = "chris_gambrell@us.ibm.com";
credentials.Password = "passw0rd";
string bookmark =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<entry xmlns=\"http://www.w3.org/2005/Atom\">" +
"<author><name>Author</name></author>" +
"<title>The Lotus Connections Page</title>" +
"<content type=
\"html\"><![CDATA[I posted this from C#]]></content>" +
"<category scheme=\"http://www.ibm.com/xmlns/prod/sn/type\" term=
\"bookmark\" />" +
"<category term=\"lotus\" />" +
"<category term=\"connections\" />" +
"<category term=\"50WaysToLeaveYourBookmark\" />" +
"<link href=\"http://www.ibm.com/lotus/connections\" />" +
"</entry>";
try
{
WebRequest request = WebRequest.Create
("https://dogear.tap.ibm.com/api/app?email=chris_gambrell@us.ibm.com");
request.Method = "POST";
byte[] byteArray = Encoding.UTF8.GetBytes(bookmark);
request.ContentType = "application/atom+xml";
request.ContentLength = byteArray.Length;
if (credentials != null)
request.Credentials = credentials;
Stream requestStream = request.GetRequestStream();
requestStream.Write(byteArray, 0, byteArray.Length);
requestStream.Close();
webResponse = request.GetResponse();
if (webResponse == null)
{
Console.WriteLine("response is null");
}
else
{
StreamReader responseReader = new StreamReader(webResponse.
GetResponseStream(), Encoding.UTF8);
Console.WriteLine("response = " + responseReader.ReadToEnd().Trim());
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e);
}
finally
{
if (webResponse != null)
{
webResponse.Close();
}
}
}
}
}
|
Groovy
by Andy Piper (http://andypiper.co.uk)
Apache Commons HttpClient - included with Groovy, but need to add commons-codec-1.3.jar to the Groovy lib directory
import groovy.xml.StreamingMarkupBuilder
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*
def xml = new StreamingMarkupBuilder().bind{
mkp.yieldUnescaped '<?xml version="1.0" encoding="UTF-8"?>\n'
entry(xmlns:"http://www.w3.org/2005/Atom") {
author() {
name 'Andy Piper'
}
title 'The Lotus Connections Page'
content(type:'html') {
mkp.yieldUnescaped '<![CDATA['
mkp.yieldUnescaped 'I posted this from Groovy'
mkp.yieldUnescaped ']]>'
}
category(scheme:'http://www.ibm.com/xmlns/prod/sn/type', term:'bookmark')
category(term:'lotus')
category(term:'connections')
category(term:'50WaysToLeaveYourBookmark')
link(href:'http://www.ibm.com/lotus/connections')
}
}
println xml.toString()
username = "andy.piper@uk.ibm.com"
password = "passw0rd"
url = "https://dogear.tap.ibm.com/api/app?email=andy.piper@uk.ibm.com"
creds = new UsernamePasswordCredentials(username, password)
client = new HttpClient()
client.getState().setCredentials(null, null, creds)
post = new PostMethod(url)
post.setRequestHeader('Content-Type','application/atom+xml')
post.setRequestBody(xml.toString())
status = client.executeMethod( post )
println(status + "\n" + post.getResponseBodyAsString())
post.releaseConnection()
|
url="https://dogear.tap.ibm.com/api/app"
entry = "<?xml version='1.0' encoding='utf-8'?>" &_
"<entry xmlns='http://www.w3.org/2005/Atom'>" &_
"<author><name>Author</name></author>" &_
"<title>The Lotus Connections Page</title>" &;_
"<content type='html'>I posted this from VBScript</content>" &_
"<category scheme='http://www.ibm.com/xmlns/prod/sn/type'
term='bookmark' />" &_
"<category term='lotus' />" &_
"<category term='connections' />" &_
"<category term='50WaysToLeaveYourBookmark' />" &_
"<link href='http://www.ibm.com/lotus/connections' />" &_
"</entry>"
Set objHTTP = CreateObject("Microsoft.XMLHTTP")
objHTTP.open "POST", url, False, "wilsonje@us.ibm.com", "passw0rd"
objHTTP.setRequestHeader "Content-Type", "application/atom+xml"
objHTTP.send entry
Document.Write objHTTP.statusText
Set objHTTP = Nothing
|
Python
by Bill Grant (billgrant.org)
base64 - encoding module
xml.dom.minidom - simple DOM module
urllib2 - url fetch module
import string
import base64
import xml.dom.minidom
import urllib2
from urllib2 import Request, urlopen, HTTPError, URLError
def create_bookmark(user, pw):
doc = xml.dom.minidom.Document()
doc.encoding = "utf-8"
entry = doc.createElement("entry")
entry.setAttribute("xmlns", "http://www.w3.org/2005/Atom")
doc.appendChild(entry)
# Author
# <author><name>Author</name></author>
author = doc.createElement("author")
entry.appendChild(author)
name = doc.createElement("name")
author.appendChild(name)
nameTXT = doc.createTextNode("Author")
name.appendChild(nameTXT)
# Title
# <title>The Lotus Connections Page</title>
title = doc.createElement("title")
entry.appendChild(title)
titleTXT = doc.createTextNode("The Lotus Connections Page")
title.appendChild(titleTXT)
# content
# <content type="html"><![CDATA[I posed this from <language>]]>
</content>
content = doc.createElement("content")
content.setAttribute("type", "html")
contentTXT = doc.createCDATASection("I posted this from Python")
content.appendChild(contentTXT)
entry.appendChild(content)
# category
# <category scheme="http://www.ibm.com/xmlns/prod/sn/type"
term="bookmark" />
category = doc.createElement("category")
category.setAttribute("scheme", "http://www.ibm.com/xmlns/prod/sn/type")
category.setAttribute("term", "bookmark")
entry.appendChild(category)
# category: tags
# <category term="lotus" />
# <category term="connections" />
# <category term="50WaysToLeaveYourBookmark" />
categoryTerm1 = doc.createElement("category")
categoryTerm1.setAttribute("term", "lotus")
entry.appendChild(categoryTerm1)
categoryTerm2 = doc.createElement("category")
categoryTerm2.setAttribute("term", "connections")
entry.appendChild(categoryTerm2)
categoryTerm3 = doc.createElement("category")
categoryTerm3.setAttribute("term", "50WaysToLeaveYourBookmark")
entry.appendChild(categoryTerm3)
# link
# <link href="http://www.ibm.com/lotus/connections" />
link = doc.createElement("link")
link.setAttribute("href", "http://www.ibm.com/lotus/connections")
entry.appendChild(link)
theData = doc.toxml("utf-8")
# headers
# Host: www.company.com
# Content-Type: application/atom+xml
# Authorization: Basic RG9uIFF1aXhvdGU6Um9jaW5hbnRl
theRequest = urllib2.Request("https://dogear.tap.ibm.com/api/app", theData)
theRequest.add_header("Host", "dogear.tap.ibm.com") # dogear.tap.ibm.com
theRequest.add_header("Content-Type", "application/atom+xml")
theRequest.add_header("Authorization",
string.strip("Basic " + base64.encodestring("%s:%s" % (user, pw))))
try:
theResponse = urllib2.urlopen(theRequest)
except HTTPError, e:
if (e.code == 201):
print "Bookmark created successfully."
else:
print "Bookmark was not created. (" + str(e.code) + ")"
if __name__ == '__main__':
create_bookmark("myemail@us.ibm.com", "mypassword")
|
Well, we didnât quite make 50, but as the 18 examples show, there are many different ways to access the AtomPub-based API on the Dogear server. The authors have shown that writing a bookmark to the server is possible using a variety of techniques and languages.
Weâve seen instances where the author has relied entirely on shell utilities such as cURL or wget, others that use libraries for HTTP access and atom entry creation, and yet others that rely on few libraries at all. Check the resources below for a link to the Lotus Greenhouse if youâd like to check out Dogear for yourself.
Learn
-
Read the developerWorks article, "Deploying IBM Lotus Connections: Integrating with other systems."
-
Visit the developerWorks Lotus Connections page.
-
Visit the Lotus Greenhouse for access to a running version of Dogear.
-
Read the Lotus Connections V1.0 Reviewer's Guide.
-
Consult the Lotus Connections documentation page for details on the installation, configuration, and administration of Lotus Connections.
-
Learn more about the Atom Syndication Format and Publishing Protocol.
Discuss
- Participate in the discussion forum.
-
Participate in the developerWorks Lotus team blog.
Frank Jania is currently the Technical Evangelist for IBM's Real Time Collaboration and Social Computing Technologies. Take a look at his social software blog.
Sacha Chua (sachac@ca.ibm.com) is a technical evangelist, storyteller, and geek. Her personal blog is at http://sachachua.com .
Axel Magard (axel_magard@de.ibm.com) is a project manager who sometimes also loves to do some computer programming. You can read his personal blog.
Jeff Lowrey (jlowrey@us.ibm.com) works for IBM Software Services for WebSphere as a Message Broker and MQ consultant and posts way too much, but not enough to his blog.
Andy Piper (andy.piper@uk.ibm.com) is a consultant working in IBM Software Services for WebSphere in the UK. His personal blog is at http://andypiper.co.uk/ .
Suzanne O Minassian (minassian@us.ibm.com) is the product manager for Lotus Connections. Her landing page is http://www.tekmoda.com .
Dave Griffiths (dgriff@uk.ibm.com) is a Java service drone. His home page is http://w3.hursley.ibm.com/~dgriff .
Chris Gambrell (chris_gambrell@us.ibm.com) is a software architect for IBM Lotus Sametime and other real-time collaboration projects.
Adam Reed (reedna@us.ibm.com) is an intern/soon-to-be part-time web developer for IBM Lotus Connections - Activities.
Comments (Undergoing maintenance)





