Born social – Create a Social Notes application from scratch

Introduction

A long time ago (it seems) I had the idea to prepare integration of Connections with Xpages development via the SBTSDK. I thought this would be a good way to learn Connections and it’s API more in details. By setting up custom controls you would be able to build mash-up apps piece by piece.

However there seemed to be little interest for this in the market (correct me if I am wrong) so I continued with other technologies.

Lately Mark Roden posted a couple of posts on his blog regarding the social business toolkit so I hop on to this and post my previous work. Hopefully it can help someone getting started.

Downloads

Born Social – the doc

The document Born Social describes how to setup your server, development environment and application to get started developing with the SBTSDK.

It also provide code samples of custom controls to display information from IBM Connections.

born social

Previous Posts on SBT SDK

Perhaps it helps to read some previous posts I wrote on the SBT SDK.

Born Social – the app

The following file contains an NSF file with all the code, custom controls and some sample xpages.

born social app

Summary

I hope the provided samples and guidance will help you to get started with the SBT SDK.

At IBMConnect at the IBM developers booth I asked what the upcoming plans where for SBT SDK and if we could get more controls for XPages but the answer was that IBM had received very few questions for application development with Connections :-/

Perhaps if more people debunk this mind-set at IBM, perhaps by sharing their samples, interest will grow.

Custom control to display a My Communities list

In the managed bean I described in an earlier post there was a method to return a list of communities in IBM Connections where the authenticated user is member of (getMyCommunities()). So what can you do with it?

In IBM Connections when you section Communities \ I’m a Member you get to see a list with communities you particpate in, along some sub data for each community:

Screenshot_4

 

Social Business Toolkit API

I find the following link the best resource to discover the details of the SBT API. For all the classes their methods are described (at least I hope so).

So for example the Community class I have created a dataTable component and added a column for all it’s methods. When I bind this dataTable to my getMyCommunities method I get an overview of what information I can re-use. If you know an easier way to check this then please drop a comment how to perform this.

dataView control

You have several options to display information from a Community list in XPages. First you have the dataTable control but this control gives you very little control about the layout. The repeat control gives you probably the greatest freedom to define your layout. But in this example I have chosen the dataView control because it has already so predefined layout structure from which you can deviate (facets). To complete the presentation I have wrapped the dataView control in a widgetContainer control.

Here is the code:

<xe:widgetContainer
id=”widgetContainer1″
titleBarText=”My communities”>
<xp:panel>
<xe:dataView
id=”dataView1″
value=”#{javascript:ServiceBean.getMyCommunities();}”
var=”comm”
rows=”5″
expandedDetail=”true”
columnTitles=”true”>
<xp:this.facets>
<xe:pagerSizes
id=”pagerSizes1″
xp:key=”pagerBottomLeft”
for=”dataView1″>
</xe:pagerSizes>
<xp:image
url=”#{javascript:return comm.getLogoUrl();}”
id=”image1″
xp:key=”icon”
style=”height:64px;width:64px”>
</xp:image>
<xp:panel xp:key=”detail”>
<xp:panel>
<xp:text
escape=”true”
id=”commMemberCount”>
<xp:this.value><![CDATA[#{javascript:return comm.getMemberCount();
}]]></xp:this.value>
<xp:this.converter>
<xp:convertNumber
type=”number”
integerOnly=”true” />

</xp:this.converter>
</xp:text>
people
<xp:span
role=”presentation”
styleClass=”lotusDivider”>
|
</xp:span>
Updated by:

<xp:link
escape=”true”
text=”#{javascript:return comm.getContributor().getName();}”
id=”commMemberUpdatedBy”>
<xp:this.value><![CDATA[#{javascript:
try {
var colleagueId = comm.getContributor().getUserid()
var profileService = new com.ibm.sbt.services.client.connections.profiles.ProfileService();

var profile = profileService.getProfile(colleagueId);
var profileUrl = profile.getProfileUrl().replace(“/atom/profile.do”, “/html/profileView.do”);

return profileUrl;
} catch (exception) {
println(“Colleague Profile error: ” + exception);
return null;
} }]]></xp:this.value>
</xp:link>
<xp:span
role=”presentation”
styleClass=”lotusDivider”>
|
</xp:span>
<xp:text
escape=”true”
id=”commUpdatedBy”
value=”#{javascript:comm.getUpdated();}”>
<xp:this.converter>
<xp:convertDateTime
type=”both”
dateStyle=”full”
timeStyle=”short”>
</xp:convertDateTime>
</xp:this.converter>
</xp:text>
<xp:span
role=”presentation”
styleClass=”lotusDivider”>
|
</xp:span>
<xp:repeat
id=”repeat1″
rows=”30″
value=”#{javascript:comm.getTags();}”
var=”rowData”
indexVar=”rowIndex”
disableTheme=”true”
disableOutputTag=”true”>
<xp:link
escape=”true”
text=”#{javascript:rowData}”
id=”link1″
styleClass=”tagLink”>
</xp:link>

</xp:repeat>
</xp:panel>
<xp:panel tagName=”div”>
<xp:text
escape=”true”
id=”commSummary”
value=”#{javascript:comm.getSummary();}”>
</xp:text>
</xp:panel>

</xp:panel>
<xp:panel
id=”titlePanel”
style=”white-space:nowrap;”
xp:key=”summary”>
<h4>
<xp:link
escape=”true”
id=”link6″
target=”_blank”
value=”#{javascript:return comm.getCommunityUrl();}”
text=”#{javascript:return comm.getTitle();}”>
</xp:link>
</h4>
</xp:panel>
</xp:this.facets>
<xe:this.extraColumns>
<xe:viewExtraColumn
value=”#{javascript:comm.getCommunityType();}”
columnTitle=”Type”>

</xe:viewExtraColumn>

<xe:viewExtraColumn
value=”#{javascript:comm.getForumTopics().length;}”
columnTitle=”Topics”>
<xp:this.converter>
<xp:convertNumber
type=”number”
integerOnly=”true” />

</xp:this.converter>

</xe:viewExtraColumn>

</xe:this.extraColumns>
<xp:this.facets>
<xp:pager
xp:key=”pagerBottomRight”
pageCount=”5″
partialRefresh=”true”>
<xp:pagerControl
type=”Previous”
id=”pagerControl4″>
</xp:pagerControl>
<xp:pagerControl
type=”Group”
id=”pagerControl5″>
</xp:pagerControl>
<xp:pagerControl
type=”Next”
id=”pagerControl6″>
</xp:pagerControl>
</xp:pager>
</xp:this.facets>

</xe:dataView>
</xp:panel>
</xe:widgetContainer>

(If you know how to paste indented code proper in WordPress than drop a comment)

The result is as followed:

Screenshot_5

I have not finished the filtering option when clicking a tag (link control). Sorting options by Date, Popularity, Name are also not in place.

Nevertheless I have a starting point to mash up this dataView control with data inside Domino 🙂

(extended) Managed Bean for SBT SDK

In a previous post I mentioned my blogpost ‘Developing social applications with the Social Business Toolkit SDK‘. In the post I defined a managed bean to connect to the Files service  and return data via the getMyFiles method. In this post I will extend that bean to access other services in IBM Connections:

  • Activity Stream
  • Blogs
  • Bookmarks
  • Communities
  • Files
  • Forums
  • Profiles

Later I will refine the ServiceBean object with new methods derived from the ones available in the SBT SDK. I shall also provide UI examples (custom controls) to present the information from the services.

ServiceBean

For now I have come so far:

package com.quintessens.bornsocial.sbt;

import java.io.Serializable;

import com.ibm.sbt.services.client.connections.activitystreams.ActivityStreamEntityList;
import com.ibm.sbt.services.client.connections.activitystreams.ActivityStreamService;
import com.ibm.sbt.services.client.connections.blogs.BlogList;
import com.ibm.sbt.services.client.connections.blogs.BlogService;
import com.ibm.sbt.services.client.connections.bookmarks.BookmarkList;
import com.ibm.sbt.services.client.connections.bookmarks.BookmarkService;
import com.ibm.sbt.services.client.connections.communities.CommunityList;
import com.ibm.sbt.services.client.connections.communities.CommunityService;
import com.ibm.sbt.services.client.connections.files.FileList;
import com.ibm.sbt.services.client.connections.files.FileService;
import com.ibm.sbt.services.client.connections.files.FileServiceException;
import com.ibm.sbt.services.client.connections.forums.ForumList;
import com.ibm.sbt.services.client.connections.forums.ForumService;
import com.ibm.sbt.services.client.connections.forums.TopicList;
import com.ibm.sbt.services.client.connections.profiles.Profile;
import com.ibm.sbt.services.client.connections.profiles.ProfileList;
import com.ibm.sbt.services.client.connections.profiles.ProfileService;
import com.ibm.sbt.services.client.connections.profiles.ProfileServiceException;

public class ServiceBean implements Serializable {
private static final long serialVersionUID = 1L;

public ActivityStreamEntityList getAllStatusUpdates() {
ActivityStreamService service = new ActivityStreamService();
try {
return service.getAllUpdates();
} catch (Throwable e) {
return null;
}
}

public ActivityStreamEntityList getMyStatusUpdates() {
ActivityStreamService service = new ActivityStreamService();
try {
return service.getMyStatusUpdates();
} catch (Throwable e) {
return null;
}
}

public ActivityStreamEntityList getMyNetworkStatusUpdates() {
ActivityStreamService service = new ActivityStreamService();
try {
return service.getStatusUpdatesFromMyNetwork();
} catch (Throwable e) {
return null;
}
}

public ActivityStreamEntityList getMyNetworkUpdates() {
ActivityStreamService service = new ActivityStreamService();
try {
return service.getUpdatesFromMyNetwork();
} catch (Throwable e) {
return null;
}
}

public ActivityStreamEntityList getUpdatesIFollow() {
ActivityStreamService service = new ActivityStreamService();
try {
return service.getUpdatesFromPeopleIFollow();
} catch (Throwable e) {
return null;
}
}

public FileList getMyFiles() {
FileService service = new FileService();
try {
return service.getMyFiles();
} catch (FileServiceException e) {
return null;
}
}

public ProfileList getMyColleagues() {
ProfileService service = new ProfileService();
try {
Profile profile = service.getMyProfile();
ProfileList profiles = service.getColleagues(profile.getUserid());
return profiles;
} catch (Throwable e) {
return null;
}
}

public Profile getMyProfile() {
ProfileService service = new ProfileService();
try {
Profile profile = service.getMyProfile();
return profile;
} catch (Throwable e) {
return null;
}
}

public BlogList getAllBlogs() {
BlogService service = new BlogService();
try {
BlogList entries = service.getAllBlogs();
return entries;
} catch (Throwable e) {
return null;
}
}

public BlogList getMyBlogs() {
BlogService service = new BlogService();
try {
BlogList entries = service.getMyBlogs();
return entries;
} catch (Throwable e) {
return null;
}
}

public BookmarkList getAllBookmarks() {
BookmarkService svc = new BookmarkService();
try {
BookmarkList bookmarks = svc.getAllBookmarks();
return bookmarks;
} catch (Throwable e) {
return null;
}
}

public BookmarkList getPopularBookmarks() {
BookmarkService svc = new BookmarkService();
try {
BookmarkList bookmarks = svc.getPopularBookmarks();
return bookmarks;
} catch (Throwable e) {
return null;
}
}

public BookmarkList getMyBookmarks() {
BookmarkService svc = new BookmarkService();
try {
BookmarkList bookmarks = svc.getMyNotifications();
return bookmarks;
} catch (Throwable e) {
return null;
}
}

public CommunityList getAllCommunities() {
CommunityService svc = new CommunityService();
try {
CommunityList comms = svc.getPublicCommunities();
return comms;
} catch (Throwable e) {
return null;
}
}

public CommunityList getMyCommunities() {
CommunityService svc = new CommunityService();
try {
CommunityList comms = svc.getMyCommunities();
return comms;
} catch (Throwable e) {
return null;
}
}

public ForumList getMyForums() {
ForumService svc = new ForumService();
try {
ForumList forums = svc.getMyForums();
return forums;
} catch (Throwable e) {
return null;
}
}

public TopicList getMyForumsTopics() {
ForumService svc = new ForumService();
try {
TopicList forums = svc.getMyForumTopics();
return forums;
} catch (Throwable e) {
return null;
}
}

}

My communities sample

Below you see an example of a widget showing the communities I am member of:

Screenshot_1

The code for the custom control is as followed:

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view
xmlns:xp=”http://www.ibm.com/xsp/core&#8221;
xmlns:xe=”http://www.ibm.com/xsp/coreex”&gt;

<xe:widgetContainer
id=”widgetContainer1″
titleBarText=”My communities”>
<xp:panel>
<xp:dataTable
id=”dataTable1″
rows=”5″
value=”#{javascript:ServiceBean.getMyCommunities();}”
var=”comm”>
<xp:column
id=”column4″>
<xp:this.facets>
<xp:label
value=”Community”
id=”label4″
xp:key=”header” />
</xp:this.facets>
<h4>
<xp:link
escape=”true”
text=”#{javascript:comm.getTitle()}”
id=”link1″
value=”#{javascript:comm.getCommunityUrl()}”
title=”Open community…” />
</h4>
</xp:column>
<xp:column
id=”column5″>
<xp:this.facets>
<xp:label
value=”Creator”
id=”label5″
xp:key=”header” />
</xp:this.facets>
<xp:text
escape=”true”
id=”computedField4″>
<xp:this.value><![CDATA[#{javascript:var d = comm.getContributor().getName();
return d;
}]]></xp:this.value>
<xp:this.converter>
<xp:convertDateTime
type=”date”
dateStyle=”short” />
</xp:this.converter>
</xp:text>
</xp:column>
<xp:column
id=”column6″>
<xp:this.facets>
<xp:label
value=”Type”
id=”label6″
xp:key=”header” />
</xp:this.facets>
<xp:text
escape=”true”
id=”computedField5″
value=”#{javascript:comm.getCommunityType() }”>
<xp:this.converter>
<xp:convertNumber
type=”number”
integerOnly=”true” />
</xp:this.converter>
</xp:text>
</xp:column>
</xp:dataTable>
<xp:pager
layout=”Previous Group Next”
partialRefresh=”true”
id=”pager1″
for=”dataTable1″ />
</xp:panel>
</xe:widgetContainer>
</xp:view>

Some thoughts

The presentation of the data from the services in Connections may vary for each type of information. Some information is more suitable to present in a tabular format, others e.g. in a Data View control. Also at this moment I am not fully aware about the available methods for each service and what data they may provide. Here the trial and error method I will simply apply, or provide multiple UI’s for the same type of information.

Time to publish this blog so I can continue with the presentation layer…

Developing social applications with the Social Business Toolkit SDK

Last week I have posted a blog item on the company blog, which you can read here. In this post I take you through the first steps how to enable a IBM Notes application to integrate with IBM Connections via the Social Business Toolkit SDK using XPages.

Learning Connections

I have the idea to build a set of custom controls which would allow you to quickly create mash-up applications to interact with IBM Connections and include them back in Connections or run them as stand alone apps. This approach allows me also to take a look at the services within IBM Connections. Once ready I will make my code available somewhere.

Inspiration

I found a great deal of inspiration in the following apps:

If you happen to know more application examples / code to integrate with IBM Connections please drop a link.