Nyheter i Domino 10, Domino 11 och lite om Connections

Posted by:

Sista veckan i februari höll HCL öppet hus i Milano och pratade om vad de planerar att göra med IBM Collaboration produkterna, som de håller på att köpa från IBM. Precis innan det var det IBM Think 2019 i San Francisco, där också en hel del nytt presenterades för framförallt Domino. Beträffande själva köpet så vet vi inte så mycket mer än att allt tyder på att det verkar bli av och att HCL tänker ge Domino en nystart.

 

Några spännande grejor som ser ut att komma med Domino 11 under Q4 2019.

 

  1. Domino som Elastic Search provider. Elastic Search kommer äntligen att kunna ersätta Dominos fulltextindex, som i mina ögon överlevt sig själv med många år. För att inte störa bakåtkompabiliteten kan Elastic aktiveras applikation för applikation.

 

  1. HTTP-autentisering mot ID Vault vilket bl.a. förenklar lösenordshantering. ID Vault blir i allt bättre med APIer etc., vilket i sig fått Dominos katalog att fungera lite mer som t.ex. Active Directory. som t.ex. inte haft Dominos problem med t.ex dubbla lösenord och klientberoenden.

 

  1. Apropå Active Directory så kommer också en helt ny AD synk.

 

  1. Ny installerare – InstallAnywhere 2018 ersätter InstallShield som gick ur tiden för länge sedan

 

  1. Domino Publisher – Snärtigare eventhanterare för både publicering- och prenumerationer knutna till databasevents och document events.

 

To be continued…. Jag skall försöka uppdatera den här posten efterhand som mer information släpps från HCL och IBM

 

Nya Domino 10 funktioner som redan släppts eller släpps efterhand

 

  1. En app (Domino Mobile Apps, kodnamn Nomad) som kör traditionella Notes-applikationer direkt från Ipads sluttestas just nu och efter den kommer även Nomad för iPhone, Android och ChromeOS. Apple versionerna av Nomad verkar distribueras via Apples B2B app store. Infoware har testat Nomad med gott resultat och vi följer utvecklingen.

 

  1. Notes-applikationsstöd som WebAssembly komponent. Nomad är också byggd för att kunna kompileras enligt WebAssembly-standarden. WebAssembly är en ny standard för att köra binärer på webb oavsett webbläsare. Web browser pluginen verkar alltså komma tillbaka, men betydligt tunnare och mer standardbaserad än tidigare. Tillsammans med ID-Vault för både Notes och http så kan det nog bli riktigt smidigt att köra både webb- och traditionella Notes applikationer från både webbläsare och mobiler https://en.wikipedia.org/wiki/WebAssembly

 

  1. Domino Query Language

 

DQL – Domino Query Language släpptes i december 2018 med Domino 10.0.1. DQL är ett nytt blixtsnabbt sätt/API/Språk för att hämta data från Domino. Om jag förstått det rätt så kommer DQL t.ex. att kunna ersätta t.ex. sök och NoteCollections i Domino applikationer.

 

  1. Domino Query Language Explorer är en Notes databas byggd för att testa DQL och få frågorna översatta till java, lotusscript eller javascript.

https://www.youtube.com/watch?v=rJNqjfML9-I

Presentationen är 11 minuter. Riktigt snyggt.

 

  1. Domino AppDev Pack 1.0 har släpptes tillsammans med Domino 10.0.1 och nu siktar HCL på att följa upp det med en ny release varje kvartal. Målet med Domino AppDev pack är att möjliggöra modernare Domino utveckling baserat på Node.js, javascript tillsammans med Domino Query Language.

 

Connections framtid, vad händer där?

HCL verkar satsa lika hårt här, även om planerna inte verkar lika klara som för Domino. Några saker har dock sipprat ut

  1. Release-tempot ökas upp till ett nytt Feature pack per kvartal och paketen utlovas att innehålla mer nytt. Senast nu under Q1 släpptes IC6 CR4 med bland annat en funktion för att dela enskilda filer externt m.h.a. direktlänkar som sedan inte kräver inloggning. Den funktionen har iallafall jag längtat efter. Infoware släpper förresten DomainPatrol Social support för IC6 CR4 nu i dagarna.
  2. IBM Connections kund-Jams för att samla input framåt är igång nu i stil med HCLs Jams inför Domino 10 och senast Domino 11

 

Länkar till mina viktigaste källor

 

Bra sammanfattning om IBM Collaboration på IBM Think nu under februari 2019

http://domino.elfworld.org/this-is-what-happened-at-ibm-think-2019/

 

Bra sammanfattning från HCLs konferens i Milano nu sista veckan i februari 2019

http://www.c3ug.ca/c3ug-blog/2019/3/1/hcl-factory-tour-episode-2-a-new-base-a-new-hope-a-new-beginning

_______________________________________________________________________________________________

Picture copyright and cudos belongs to colleague and photographer Tony Andersson

https://500px.com/tonyandersson

 

 

 

 

 

0

Delivering responsive web design in IBM Notes applications

Posted by:

Introduction

Responsive web design (RWD) has been the talk of town the last years. In 2012 it was listed as #2 in ‘Top Web Design Trends’ by .net magazine and Mashable called 2013 the ‘Year of Responsive Web Design’. Many other sources have recommended responsive design as a cost-effective alternative to mobile applications.

responsive

While I assume that a large portion of the internet (and in some cases intranet) sites are nowadays optimized for the device that accesses them, but what about your company’s (internal) business applications? 

Business value

IT departments need to prioritize their activities and internal applications are most often accessed by a smaller audience than external applications. Historically the internal app was accessed with a desktop computer. With the trend of smartphones and tablets taking over the workspace this may no longer be the case in your company? 

With a VPN connection users want to continue to execute their work on this new breed of devices, instead starting up a desktop computer for a single task. Here is where the business value of RWD comes in.

Continue to work on same device = More productive employees = Saving time and perhaps even hardware

Mobile first

A trend is to apply the progressive application strategy of ‘Mobile first’. Instead of designing a complex application for desktop computers first and thereafter gracefully degrade it for mobile devices, the user interface is initially designed for mobile devices and enhanced for desktops with more processing power.

mobile-first-icons

Many RWD frameworks embrace this ‘Mobile first’ concept nowadays.

Options in Notes

So what are your options in delivering RWD in your beloved Notes applications? Depending on your roadmap for the platform and personal preferences you have the following options.

  1. Build the application with XPages technologies.
  2. Build the application with common web technologies.

The XPages way

An approach for your Notes platform that is highly promoted by IBM is to deliver web interfaces for Notes applications with XPages. Not only bring you in Rapid Application Development (RAD) principles in your project also the range of capabilities is much more diverse.

Another benefit is that you can stay on the core technologies: JSF, JavaScript and Java. This you can combine with common web technologies like AJAX, HTML5, CSS and REST services. For the RWD you can use your favorite framework such as Bootstrap or Foundation.

Bootstrap framework

twitter-bootstrap

Bootstrap is a popular framework for developing responsive, mobile first projects on the web. It makes front-end web development faster and easier. Bootstrap is based upon HTML, CSS and JavaScript, technologies already well-known in Notes web apps.

Distribution

You have several options how you distribute the Bootstrap framework to your audience:

  1. Install the files on your Domino server.
  2. Embed the files in a Notes application.
  3. Install an additional XSP library on your Domino server.
  4. Install the latest extension library on your Domino server.

In case you do not utilize the OSGi runtime on your Domino server you can either install the files on centrally on the Domino server or embed the files in each Notes application. The installation on the Domino server makes the distribution of updates easier but the administrator is responsible for the distribution across servers. Embedding the files in a Notes application is less efficient (e.g. caching) but makes distribution of updates a task for the developer.

Probably the best approach would be to utilize the OSGi runtime on your Domino server and distribute the files as a library via an Update site Notes application across your servers. This makes the task even simple and small for an administrator.

If you choose to do so you have the option to either install bootstrap4xpages library as a separate library or you can install the latest extension library (from 10 november 2014). The latter give you several benefits:

  • Custom renderer for the Application Layout control, which makes it easy to define the layout structure of your application.

     

     

    • This renderer gives the control a Bootstrap look & feel, as well making the control responsive.
  • A newer version of jQuery.
  • Latest Bootstrap themes (3.2.0 normal or flat).
  • Additional configuration options in the Application Layout control wizard for the Bootstrap navigation components.

Separate Mobile devices UI alternative

The extension library (a library with additional XPages controls and functions) provides also so-called ‘Mobile controls’ which allow you to deliver a separate interface for mobile devices for your Notes apps. Via a wizard you can build a ‘single page application’ in a matter of minutes with full CRUD (create, read, update and delete) operations and infinite scrolling through document lists (aka views).

This approach does not deliver RWD but a separate user interface for mobile devices. At least it gives you the option to deliver a UI adapted for mobile devices in a very short time with little investment.

You can choose to make the UI of the app look like a native app for iPhone or Android. Alternatively you can choose to make the UI look in line with other IBM products (iNotes, Connections). A video that demonstrates the controls briefly you can find here: http://vimeo.com/99537780.

The WEB way

In case you do not walk the XPages path but instead you prefer the approach to deliver the application with more common web technologies like HTML, CSS, AJAX and REST services you can still install the files of your responsive web design framework of choice on the Domino server or embed them in a Notes application.

From there you can start to (re)write your ‘traditional’ Domino application as a Web project. In the latter case you use Notes only as a container for your data documents and design elements and use forms and views only as data schemes.

This approach dodges the RAD capabilities in Notes and will demand more development time. But you can apply this approach also to other platforms that you may have. You can later even debate why the data should be stored in Notes and not in a document-oriented database alternative? The layered security and replication capabilities are often good arguments. 

Implementing RWD via the Extension Library option

In the following scenario we will describe the implementation of RWD with the Extension Library more in details.

  • Database enablement.
  • Application Layout.

Database enablement

Assuming you have installed the extensions for the Domino server and Domino Designer (DDE) client according the instructions in the readme.pdf file you can now enable a Notes application.

XSP properties

The XSP properties file allows you to configure parameters for the XPages framework. Open the file in DDE.

Screenshot_1

In the General tab you have now two more themes to select:

  • Bootstrap 3.2.0
  • Bootstrap 3.2.0 flat

The ‘flat’ theme delivers:

  • The resources and styling that comes with Bootstrap v3.2.0.
  • jQuery v2.1.1 resources.
  • Cleanup of specific XPages controls when using Bootstrap.
  • Glyphicon halflings.
  • dbootstrap resources, which provide Bootstrap styling for Dojo controls.

The ‘ordinary’ theme provides all of the same resources as the flat theme, and includes 3D effects to buttons and some other additional styling.

Select one of the two themes:

Screenshot_2

Application layout

The RWD plugin adds a new renderer for the Application Layout control which you normally use to structure the layout of your application. This renderer gives your application layout the Bootstrap look and feel, as well as responsive behavior. When the application is rendered on a smaller screen, such as on a mobile device, it will automatically re-organize the application contents for an optimal user experience.

The control also has new configuration options. Add the Application control on a custom control and open the All Properties tab. In the basics section you can choose now the xe:bootstrapResponsiveConfiguration option:

Screenshot_3

Note: in case you have already a configured Application Layout control you can change the configuration option directly in the Source panel to keep the rest of your configuration (e.g. xe:applicationConfiguration -> xe:bootstrapResponsiveConfiguration).

This configuration options give you several more properties:

  • collapseLeftColumn
  • collapseLeftMenuLabel
  • collapaseLeftTarget
  • fixedNavbar
  • invertedNavbar
  • pageWidth

With the first 3 properties you define how the left column should behave on smaller devices (collapsed for smaller devices, display text when collapsed, item the left menu should be attached to).

You can determine the behavior of the navbar (inverted, fixed (top or bottom)) and the width of the page e.g. fluid = use Bootstrap 'fluid' container (almost full width).

Wizard

When you initially drag on the Application Layout control on the custom control a two-step wizard is presented. In the first step you select one of available configurations. You can filter on responsive and non-responsive.

Screenshot_4

In the second you set the properties for the chosen configuration. In case you choose the Responsive Bootstrap option you will see the following screen:

Screenshot_5

Under configuration you can set the properties for the layout including the 6 additional properties mentioned earlier. Set also the other properties like you would normally do.

Voila! Your application is now ready for development.

Hiding elements for specific devices

The plugin provides only the resources and structure for responsive web design. In case you want to optimize the layout for devices by explicitly show or hide them you can use CSS classes.

Bootstrap provides some handful helper classes, for faster mobile-friendly development. These can be used for showing and hiding content by device via media query combined with large, small, and medium devices.

Classes

Devices

.visible-xs

Extra small (less than 768px) visible

.visible-sm

Small (up to 768 px) visible

.visible-md

Medium (768 px to 991 px) visible

.visible-lg

Larger (992 px and above) visible

.hidden-xs

Extra small (less than 768px) hidden

.hidden-sm

Small (up to 768 px) hidden

.hidden-md

Medium (768 px to 991 px) hidden

.hidden-lg

Larger (992 px and above) hidden

Note that the elements that you hide are still being loaded, but simply not being displayed.

Data View control

Probably a typical use case is the display of table columns or lists. On a desktop you may want to show more columns than on a smaller devices.

Typical you use the Data View control from the extension library to display lists of documents. The information you want to display as a link is defined in the summaryColumn property.

Screenshot_6

Additional columns that are displayed on the right of the summaryColumn will be displayed via the extraColumns property. Each additional column is defined in a viewExtraColumn item which contains properties for styleClass and headerStyleClass. For example you could set these as followed:

<xe:this.extraColumns>

<xe:viewExtraColumn columnName="Date" columnTitle="Date" style="width: 100px"  styleClass=" hidden-xs hidden-sm " headerStyleClass=" hidden-xs hidden-sm"></xe:viewExtraColumn>

</xe:this.extraColumns>

This will show the extra column only for medium and larger devices since they will be hidden for (extra) small devices.

Screenshot_7

Wrap up

Delivering responsive web design on your Notes applications has never been as easy as it is nowadays with the RWD plugin in the extension library. It also respects the rapid application (web) development mantra of XPages.

In case you do decide to follow this path remember you need to check what information you want to show or hide for specific devices.

So what is keeping you from getting a bigger bang for the buck by delivering optimized user experiences for mobile, tablet and desktops for your Notes applications?

 

0

Developing social applications with the Social Business Toolkit SDK

Posted by:

Intro

The Social Business Toolkit SDK (SBT SDK) is a set of libraries and code samples that you use for connecting to the IBM Social Platform. As a developer you can choose which web development skills fits you best: Java, (client side) JavaScript or XPages. Your social platform may reside in the cloud or on premise.

In this post I will give you guidelines and practical examples to get you started. I choose XPages as development environment.

Terminology

In the document terms are thoroughly used:

Term

Description

SBT

Social Business Toolkit

SDK

Software Development Kit

DDE

Domino Designer on Eclipse

XPages

XPages is a rapid web and mobile application development technology

OpenNTF

Open Source Community for (IBM) Collaboration Solutions

OAuth

Open standard for authorization

Managed Bean

Java Beans representing system objects and resources

Endpoint

Encapsulates the access to a service provider, like Connections or Sametime

Installation of the SDK

Prerequisites

Before you can start with development in Domino Designer on Eclipse you need to install the SBT SDK. It can be downloaded from the following address: http://ibmsbt.openntf.org/The files you need to work with the SBT SDK and Domino are located in folder ‘redist\domino’ in the downloaded ZIP file.

Extension Library

Another condition to be able to run the Social SDK within your XPages you need to have installed the Extension Library, available on OpenNTF: http://extlib.openntf.org/. You need to have the library installed on both Domino server and DDE.

Installation for Domino Server

You can find a set of instructions how to install the SBT SDK on an IBM Domino server on the address:
http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Social+Business+Toolkit+SDK+documentation#action=openDocument&res_title=Installing_on_Domino_Server_SDK1.0&content=pdcontent. I recommend the installation via an Eclipse Update site. As a result your Update site should display the following plugins:

Screenshot_4

Installation for DDE

The Domino Designer deployment of the IBM Social SDK can use the same imported update site from the Update Site NSF. On Domino Designer verify that the checkbox for "Enable Eclipse plugin install" is checked in the Domino Designer preferences. You can find a set of instructions how to install the SBT SDK on DDE on the same address:
http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Social+Business+Toolkit+SDK+documentation#action=openDocument&res_title=Installing_on_Domino_Server_SDK1.0&content=pdcontent.

Setting up a Notes application

Create a new Notes application from scratch. I called mine ‘bornsocial.nsf’. Open the Xsp Properties file in DDE. Include the following libraries:

  • com.ibm.xsp.extlib.library
  • com.ibm.xsp.sbtsdk.library

Screenshot_5

Authentication

The Social Business Toolkit leverages a credential store for single sign on. For OAuth for example the user tokens are stored in this repository so that users don’t have to authenticate and grant access to services like IBM Connections for every session. The OAuth application tokens are also stored in this repository so that all tokens can be managed in one central place. You can read more on the credential store here: http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Social+Business+Toolkit+SDK+documentation#action=openDocument&res_title=Configuring_token_stores_SDK1.0&content=pdcontent&sa=true. And it is also explained in the following video: http://www.youtube.com/watch?v=2CWD70XarX8#t=100

In basic: the implementation of the credential store is performed by the use of a managed bean. The usage of this credential store is then defined in an endpoint. An endpoint encapsulates the access to a service provider, like Connections or SameTime.

In the Package Explorer open the faces-config.xml file:

Screenshot_6

Add the following lines:

<!– Token Store memory implementation –>
<managed-bean>
    <managed-bean-name>CredStore</managed-bean-name>
    <managed-bean-class>com.ibm.sbt.security.credential.store.MemoryStore</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>

<!– Password Store memory implementation –>
<managed-bean>
    <managed-bean-name>PasswordStore</managed-bean-name>
    <managed-bean-class>com.ibm.sbt.security.credential.store.MemoryStore</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Endpoint

In the first example(s) we are only going to demonstrate to connect to IBM Connections. Add the following lines:

<managed-bean>
    <managed-bean-name>connections</managed-bean-name>
    <managed-bean-class>com.ibm.sbt.services.endpoints.ConnectionsBasicEndpoint</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>url</property-name>
      <value>https://your-connections-url.com</value>
    </managed-property>
    <managed-property>
      <property-name>authenticationService</property-name>
      <value>communities/service/atom/communities/all</value>
    </managed-property>
    <managed-property>
      <property-name>authenticationPage</property-name>
      <value>/bornsocial.nsf/_BasicLogin.xsp?endpoint=connections</value>
    </managed-property>
  </managed-bean>

For value of managed property ‘url’ you must enter the address of your connections installation or in case you are using IBM Greenhouse for demonstration purposes you can choose 'https://greenhouse.lotus.com’.

Login page

A custom login page will presented when a user initially tries to connect to IBM Connections:

Screenshot_7

The elements for the login page are in the XPagesSBT.nsf application which comes with the SBT SDK. The nsf is located in folder redist\domino. The login page consists of the following design elements:

Name

Type

_BasicLogin.xsp

XPage

sbtLoginPage

Custom Control

sbtLoginPanel

Custom Control

You can simply copy the design elements from the sample application in your application and modify them e.g. for branding.

Connecting to Connections

Your application is now ready to connect to Connections. Where you place the code to connect to Connections is up to you. A recommended approach could be to establish connections via Managed Beans.A managed bean is nothing more fancy than a registered a JAVA object.

Managed Bean

In our first example we are going to read the content under My Files in Connections. These are the files that you have uploaded and shared.

  1. Create a new Java design element (Java Class).
  2. Enter the following code:

package com.quintessens.bornsocial.sbt;
import java.io.Serializable;
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.files.FileList;

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

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

Code explanation

The function getMyFiles gets handle to the FileService object. Then the getMyFiles function is called to get all the files (both private and shared) the user has uploaded in Connections. Then a FileList object is returned to the caller. 

The FileList object can then be used in a suitable XPage control e.g. the DataTable or the DataView control. 

Registration

In order to access the Managed Bean you have to register it. This is done in the faces-config.xml file. Open the file and add the following lines:

 <managed-bean>
    <managed-bean-name>ServiceBean</managed-bean-name>
    <managed-bean-class>com.quintessens.bornsocial.sbt.ServiceBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
  </managed-bean>

You will access the bean via its name ServiceBean.

XPages

Finally we have come to a point where we can display the files that the managed bean returns from IBM Connections. I have choosen the XPages environment to do so.

Custom Controls

A best practice in XPages development is to divide functionality in individual blocks known as Custom Controls. This make it easier to re-use the functionality across your application.

Custom Control for a ‘My Files’ overview

  • Create a new Custom Control design element.
  • Add the following code to the control:

<xe:widgetContainer id="widgetContainer1" itleBarText="#{javascript:return compositeData.widgetTitle;}">
    <xp:panel>
        <xe:dataView id="dataView1" var="file" rows="5" columnTitles="true" styleClass="filesDataView">
            <xe:this.extraColumns>
                <xe:viewExtraColumn columnTitle="Filetype"></xe:viewExtraColumn>
                <xe:viewExtraColumn columnTitle="Created"></xe:viewExtraColumn>
                <xe:viewExtraColumn columnTitle="Size"></xe:viewExtraColumn>
            </xe:this.extraColumns>

            <xe:this.summaryColumn>
                <xe:viewSummaryColumn columnTitle="Filename"></xe:viewSummaryColumn>
            </xe:this.summaryColumn>
            <xp:this.value>
                <![CDATA[#{javascript:ServiceBean.getMyFiles();}]]>
            </xp:this.value>
            <xp:this.facets>
                <xp:panel xp:key="noRows" id="topicsPanel2">
                    <xp:div styleClass="lotusWidgetBody">
                        <xp:text>
                            <xp:this.value>
                                <![CDATA[#{javascript:return (viewScope.myFilesAvailable ? “No files found.” : “My Files unavailable.”);}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:div>
                </xp:panel>
                <xp:panel id="summaryPanel" xp:key="summary" style="width:50%;white-space:nowrap;">
                    <h4><xp:link styleClass="dataViewLink" escape="true" id="link7" target="_blank" text="#{javascript:return file.getTitle();}">
    <xp:this.value><![CDATA[#{javascript:return file.getContentUrl();}]]></xp:this.value>
</xp:link></h4>
                </xp:panel>
                <xp:panel id="typePanel" xp:key="extra0" style="width: 20%;white-space:nowrap;">
                    <xp:text>
                        <xp:this.value>
                            <![CDATA[#{javascript:return file.getType();}]]>
                        </xp:this.value>
                    </xp:text>
                </xp:panel>
                <xp:panel id="sizePanel" xp:key="extra2" style="width: 15%;white-space:nowrap;">
                    <xp:text>
                        <xp:this.value>
                            <![CDATA[#{javascript:var size = file.getSize();
var kilobyte = 1024;
var megabyte = kilobyte *1024;
if(size < kilobyte) {
    return (size + " B");
}else if(size < megabyte) {
    return (Math.round(size/kilobyte) + " KB");
}else {
    return (Math.round(size/megabyte) + " MB");
}}]]>
                        </xp:this.value>
                    </xp:text>
                </xp:panel>
                <xp:panel id="panel1" xp:key="extra1" style="width: 15%;white-space:nowrap;">
                    <xp:text escape="true" id="computedField3" value="#{javascript:file.getCreated()}"></xp:text>
                </xp:panel>
            </xp:this.facets>
        </xe:dataView>
    </xp:panel>
</xe:widgetContainer>

As a result the files in IBM Connections for the authenticated user will be listed e.g.: 

Screenshot_8

Code explanation

The DataView control is using the getMyFiles function from Managed Bean ServiceBean for data binding:

 

Screenshot_9

<xe:dataView id="dataView1" var="file" rows="5" columnTitles="true" styleClass="filesDataView">            
            <xp:this.value><![CDATA[#{javascript:ServiceBean.getMyFiles();
        }]]></xp:this.value>
            …
</xe:dataView>

It iterates through the returned FileList object and for each column values from each entry in the ‘file’ collection the value is computed e.g.:

<xp:panel id="summaryPanel" xp:key="summary" style="width:50%;white-space:nowrap;">
                    <h4><xp:link styleClass="dataViewLink" escape="true" id="link7" target="_blank" text="#{javascript:return file.getTitle();}">
                        <xp:this.value><![CDATA[#{javascript:return file.getContentUrl();}]]></xp:this.value>
                    </xp:link></h4>
 </xp:panel>

API Explorer

Use the SBT API Explorer which method each object provides:

Screenshot_10

Link: http://greenhouse.lotus.com/llapiexplorer/.

Summary

As you have seen getting started with the Social Business Toolkit is not that difficult for XPages developers. As alternative you could also choose JavaScript or JAVA if those skills fit you better. The SDK will help you understanding Connections piece by piece from a developer perspective.

In the example information is read from Connections but you can also post data. The SDK allows you to create great 'social enabled' applications. This can be applications that solely work with Connections or integrate with other platforms e.g. IBM Notes. 

I hope to write more on the Social Business Toolkit in another post. Thank you for reading.

Patrick Kwinten

 

 

 

 

 

2

Phonegap / Cordova 3.6.3 & CDVPlugin class CDVNotification (pluginName: Notification) does not exist

Posted by:

Eager to get your hands on the new and shiny huh?

Well, if you're using the plugin: org.apache.cordova.dialogs and upgraded your project to Phonegap / Cordova 3.6.3 you're in for a world of hurt.

This plugin is what provides native notifications like alert, confirm, prompt and beep. This will, after upgrading, cease to work and you should get a confusing error message in XCode like below:

(The text from row 3 and below will vary, depending on your implementation of the plugin)

2014-09-23 08:27:40.512 Rooms[7288:414440] CDVPlugin class CDVNotification (pluginName: Notification) does not exist.
2014-09-23 08:27:40.512 Rooms[7288:414440] ERROR: Plugin 'Notification' not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.
2014-09-23 08:27:40.512 Rooms[7288:414440] -[CDVCommandQueue executePending] [Line 158] FAILED pluginJSON = [
  "Notification1434422161",
  "Notification",
  "alert",
  [
    "You have to perform the setup, before you can use the application.",
    "Perform Setup",
    "Don't worry, it's easy"
  ]
]

This is how to solve it:

You need to add the plugin, manually, to the build phase of the project and you need to add a framework. Sounds complicated? It really isn't. Just have a look at the image below, follow the steps and…. BOOM! You're of to stardom once again!

 

3

JSR286 portlet unit testing with Jetty, Pluto and JWebUnit

Posted by:

Background

Unit testing using JUnit has been around for quite some time, and even though I have used in early JUnit versions, it got really going when I also started to use maven. It was quite easy to create unit tests for any of my classes. Since I worked a lot with portlets I wanted to do expand my unit tests to include portlets.

 

The JSR286 portlet standard has been around for a while and it surprised me that I couldn't find any unit tests for JSR286 portlets, only JSR168 portlets. The most helpful blog I found was this one Testing Portlets with Jetty, Pluto and JWebUnit but again it applies to JSR168 portlets. Starting from there I tried to do the same thing with JSR286 portlets, but the pluto version used wasn't designed to work with JSR286 portlet. However, it gave me a starting point to recreate the setup for JSR286 portlet unit testing.

 

Setup

I will be using only a minimalistic portlet to demonstrate the setup. My starting point is a minimalistic portlet set up with maven. I demonstrated how to set that up in my last blog entry. From there I enhanced it a bit to allow for more testing. Here is the portlet class, the portlet.xml and the jsp I am using.

package com.mycompany.myportlet;

import java.io.IOException;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class MyPortlet extends GenericPortlet {

	public void doView(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
				"/view.jsp");
		rd.include(request, response);
	}
}

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" id="MyPortlet">
	<portlet>
		<portlet-name>MyPortlet</portlet-name>
		<display-name xml:lang="en">MyPortlet</display-name>
		<display-name>MyPortlet</display-name>
		<portlet-class>com.mycompany.myportlet.MyPortlet</portlet-class>
		<expiration-cache>0</expiration-cache>
		<supports>
			<mime-type>text/html</mime-type>
			<portlet-mode>view</portlet-mode>
		</supports>
		<supported-locale>en</supported-locale>
		<resource-bundle>com.mycompany.myportlet.nl.MyPortletResource</resource-bundle>
		<portlet-info>
			<title>MyPortlet</title>
			<short-title>MyPortlet</short-title>
			<keywords>MyPortlet</keywords>
		</portlet-info>
	</portlet>
	<default-namespace>http://MyPortlet/</default-namespace>
</portlet-app>

<%@page session="false" contentType="text/html" pageEncoding="ISO-8859-1" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>                
<portlet:defineObjects/>

<div id="HelloWorldDiv">
Hello World!
</div>

Maven dependencies

Next I set up the maven configuration. For this example I am using a simple pom.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mycompany.myportlet</groupId>
	<artifactId>MyPortlet</artifactId>
	<version>0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>My Portlet</name>
	<description>A basic portlet mavenized</description>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.17</version>
				<configuration>
					<useSystemClassLoader>false</useSystemClassLoader>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>javax.portlet</groupId>
			<artifactId>portlet-api</artifactId>
			<version>2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>jetty-maven-plugin</artifactId>
			<version>7.0.0.pre5</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>net.sf.portletunit</groupId>
			<artifactId>maven-jetty-pluto-embedded</artifactId>
			<version>2.0</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>net.sourceforge.jwebunit</groupId>
			<artifactId>jwebunit-htmlunit-plugin</artifactId>
			<version>3.0</version>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>logback-classic</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.7</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

I will describe what all of this does starting at the top. It starts with the basic maven configuration for the project. Moving on to the build section. There are some issues with loading classpaths and if I don't tell the surefire plugin to not use the system classloader, jetty will not be able to find the JSTL tag library and thus the entire test will fail.

 In the dependencies section I will start with the standard portlet api. This is required to compile the portlet class. Next is the jetty-maven-plugin. This is the lightweight web container used as a web server if you will when we are running the tests. This is then used together with the maven-jetty-pluto-embedded plugin. Pluto provides the portlet engine for the portlet  and maven-jetty-pluto-embedded provides the possibility to use pluto together with jetty. Starting with version 2.0 of this plugin the JSR286 portlet specification was supported. Next is jwebunit-htmlunit-plugin. This is what I use for the actual tests in my test class. The exclusion in the dependency is for us to be using my own custom logging configuration and so is slf4j-log4j12. Also note that all of these dependencies (except for the portlet api) are using the test scope. This is because I will only require these during the test phase.

Also as a sidenote. Some of these implementations have newer versions available in particular the jetty-maven-plugin, but since one of the critical components is maven-jetty-pluto-embedded, the version I use here is the latest compatible version I have found I can use.

The test class

Now off to the test class. Basically I do this in three steps. Setting up the server, running my tests and shutting down the server.

package mytest;

import static net.sourceforge.jwebunit.junit.JWebUnit.assertElementPresent;
import static net.sourceforge.jwebunit.junit.JWebUnit.assertTextPresent;
import static net.sourceforge.jwebunit.junit.JWebUnit.beginAt;
import static net.sourceforge.jwebunit.junit.JWebUnit.getTestContext;

import org.apache.pluto.container.driver.PortletServlet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.webapp.WebAppContext;

public class MyPortletTest {
	private Server server;
	private static final int SERVER_PORT = 8080;

	@Before
	public void setUp() throws Exception {
		System.setProperty("org.apache.pluto.embedded.portletIds", "MyPortlet");
		server = new Server(SERVER_PORT);
		WebAppContext webapp = new WebAppContext("src/main/webapp", "/test");
		webapp.setDefaultsDescriptor("/WEB-INF/jetty-pluto-web-default.xml");
		ServletHolder portletServlet = new ServletHolder(new PortletServlet());
		portletServlet.setInitParameter("portlet-name", "MyPortlet");
		portletServlet.setInitOrder(1);
		webapp.addServlet(portletServlet, "/PlutoInvoker/MyPortlet");
		server.addHandler(webapp);
		server.start();
		getTestContext().setBaseUrl("http://localhost:" + SERVER_PORT + "/test");
	}

	@After
	public void tearDown() throws Exception {
		server.stop();
	}

	@Test
	public void testDoView() {
		beginAt("/portal/index.jsp");
		assertTextPresent("Hello World!");
		assertElementPresent("HelloWorldDiv");
	}
}

The startup of the server can be done also through configuration, but I extended my work starting from the blog where I found the JSR168 examples so I will continue the same way. In the setUp() method I do all of the server configuration and startup work. The exact name of the method id not important, but it must use the @Before annotation. The first line defines the portlets I use in my tests, the exact name is not important but it must match the portlet name in the portlet.xml. There can be multiple portlets as long as they are on a comma-separated list. The server is created with only a port where the server is started. The port can pretty much be any port as long as it is not already in use.

 

Next the web application context is set up. Here I define a servlet url mapping and add pluto descriptors and classes in order to get a proper portlet engine. The web application context is added to the server and the server is started. Finally the base url to use for all tests is defined.

 

The tearDown method is run after all the tests have completed (using the @After annotation). All this method does is to stop the server.

 

Finally I have the test method. This is just a simple demonstration to get started. What you want to do with your tests is up to you. Any test method can contain a number of different tests and there can be multiple tests in a test class. Here I start navigating to the pluto portals front page, making sure a certain text and div is present.

 

Reduce logging

If you run the test with only the above setup, you will find there is some extensive logging done. This is because the logging is set to debug level. I find this a bit too talky myself. In order to fix this, first we must exclude the default logging from JWebUnit. Jetty uses slf4j and all I did from there was to add the log4j impementation of slf4j using this configuration.

log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p] %c{1}:%L - %m%n

This configuration will set the logging to warn level. This will reduce the logging drastically but the cause will still be logged if an error fails. You may need to adjust the log level for further debugging if a test fails, but I found this to be a nice setting. I have also added a configuration which will output maven-like logging.

References

0

Make your portlet development use maven in no-time

Posted by:

Background

I started using maven some time back and I have found many advantages. One in particular was the ease to run unit tests. This made me want to be able to unit test portlets. The portlets I create nowadays are all based on the JSR286 standard. I did not find any examples of that, but with some help from what I found I was able to do unit testing. First things first though. Before we can use unit testing for portlets, we need to have a portlet where we also use maven. This blog entry will show you have you as simple as possible get your portlet sources mavenized. 

I will not cover the topic of why you should use portlets or maven. There are so many good resources out there already and a simple search should be easy enough to find them.

 

Basic portlet

First of all I have a really minimalistic portlet. There is only what I need to have inb order for the portlet to work. The point was to give a basic example of what you need to do to start using maven to build your portlet. In this I had the portlet class, a jsp file, the portlet.xml, the web.xml and some resource bundle property files.

 

Preparations

In order to use maven you need to have some software installed. You need to have a jdk (I used the latest available from Oracle) and maven. Make sure you have your maven binaries set in your path and your JAVA_HOME environment variable set to the directory where you installed the JDK. Note! It must be the jdk, a jre will not be sufficient in the long run.

If you just want to use the central maven repository and have direct access to Internet you don't need to do any other configuration, but if your network setup is different you may need to look at additional steps to configure maven, such as using a proxy with maven.

 

Moving files

Maven use a standard layout for its directories. You are in no way obliged to follow this standard and I am not going to even get into a discussion about what is best, I will simply leave that up to you. In this example though, I am using the standard directory layout as it makes the maven configuration easier. 

A portlet is packed in a web application archive, a war file. While maven has no direct portlet packaging available, it is not really required either as we use the war packaging, which effectively does the job. With this in mind there in particular three directories which we will use from the maven standard.

src/main/java
src/main/resources
src/main/webapp

At this step you should move all of your portlet files into these three directories.

src/main/java should contain all your java sources. It is the root directory of your java sources so if you have your classes in packages, that structure must still be intact. The compiled classes will end up in your WEB-INF/classes directory. src/main/resources contains non-java files which should end up together with your compiled classes. In this case the portlet ResourceBundle property files will be here. Again, if you are using a package structure for your resources, that structure must be intact. The resources files will be copied as is (depending on your maven configuration) to your WEB-INF/classes directory. Finally the src/main/webapp directory contains all the files which should end up in the root directory of your web application. This includes any jsps you may have as well as your META-INF and WEB-INF directories (and all the files there in such as WEB-INF/portlet.xml and WEB-INF/web.xml). 

After all of this is completed I ended up with the following file structure:

src\main\java\com\mycompany\myportlet\MyPortlet.java
src\main\resources\com\mycompany\myportlet\nl\MyPortletResource.properties
src\main\resources\com\mycompany\myportlet\nl\MyPortletResource_en.properties
src\main\webapp\view.jsp
src\main\webapp\META-INF\MANIFEST.MF
src\main\webapp\WEB-INF\portlet.xml
src\main\webapp\WEB-INF\web.xml

Maven configuration

The heart of maven configuration is the pom. It is in xml format and its name is pom.xml. This file was created in the root directory. First there was the basic stuff. I won't go into details of any of this. Some of it is fairly self explanatory, but for the rest I suggest you look at the pom reference.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany.myportlet</groupId>
    <artifactId>MyPortlet</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>My Portlet</name>
    <description>A basic portlet mavenized</description>
    <!-- The dependencies will be added here.-->
</project>

Finally the portlet apis need to be added in order for the portlet class to be compiled. For this we add a dependency. A dependency is really what the name implies. In order to compile and build our portlet we have a dependency on another library (apart from standard java) in this case the portlet api. For this portlet to work only the portlet api is needed, but there may be many dependencies. Note the scope in this dependency. With the scope of provided we are telling maven that this dependency will be provided later on, we only need to use it now at compile time. This is true because the portlet libraries are provided by the portlet container when we run the portlet. The libraries should not be included in our war file.

<dependencies>
    <groupId>javax.portlet</groupId>
    <artifactId>portlet-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
    </dependency>
</dependencies>

Building

Now we are done and we are ready to build. The command to build, package and verify as much as possible without adding our built war to the local or remote repository is mvn verify. If all has been done right you should get a BUILD SUCCESSFUL message in the end.

 

References

Cross-post

http://danielsdeveloperblog.blogspot.se/2014/08/make-your-portlet-development-use-maven.html

0

5 minutes of effort = 1600% increase in performance

Posted by:

So, the other day I was humming along for one of our larger clients – putting the finishing touches on one of their applications. The app in question handles matching of vacancies against applications. The administrator needs to quickly have the ability to browse what vacancies have what status. 

One vacancy can have one of three different statuses:

  1. View – Show the selected application for this vacancy.
  2. List – Lists all matching applications for this particular vacancy.
  3. Missing – No current applications exists that match the criteria for this vacancy.

Don't worry too much about the business logic, I only provide a quick background to give you some idea of what I was trying to achieve.

 

Oh, I nearly forgot! Of course this is an IBM Domino solution as we are a "True Blue" IBM Premium Business partner. Unfortunately this client was stuck with a fairly old IBM Domino server: 8.5.2, so I wasn't too keen on using an XPages solution. Why? Because in my humble opinion XPages just hadn't matured enough yet. (Missing HTML5 features, no SSJS debugger, old DOJO release, loooong "first hit" boot times and so on – Yes, all of this can be mended, worked around, patched etc. But sometimes you can just say enough is enough and go with old school Domino development.)

Anywho, my first inclination was to create a WebQuerySave agent that did the matching ServerSide before presenting the result to the user, a very common approach. But the performance was really bad – The WQS agent took around 4000ms although the workload was light and number of documents fairly low (in the hundreds anyway). The page itself took around a second to load with an empty cache, so we we're looking at a total page load time here in the neighborhood of five seconds – not acceptable.

So I used an approach that's known as perceived performance. Let's take a clock as example – If you use a clock that doesn't show seconds, time seems to move slower. If there's a lot of stuff going on, the general experience is that things are happening quicker. So I extracted my LotusScript code and placed it in an agent that get's called thru AJAX. This way the page loads quickly, the user can start to interact with it immediately and the state of each vacancy trickles in as the server sees fit.

Below is a screenshot of the application, waiting for the AJAX request to comeback with the data. (The only vacancies that know its state are the ones that are booked, they're marked with "Visa" in the column to the right, the rest are pending).

 

Finally, here we have the first icarnation of the code:

Nothing too odd about the above, I would even dare to say a fairly common approach. I do what I can to speed up the process by using NotesViewEntryCollections and the ColumnValue-property. Using one view as the source, that has a column that combines the particular criteria for that vacancy. The key can look something like this:

2015-05-27DSurgeon (Date + Slot + Role)

We use this key to find any matching requests, if none is found it's added to the string that's returned to the AJAX request. We only need the ones that doesn't have a match (Missing) as the first state (View) is stored with the vacancy and the second state (List) are all that are not missing. Ideally "Missing" should always be very few documents so the data transfer over the wire should also be low, increasing performance further.

 

So, everything was "hunky-dory" then. The application loaded quickly and felt responsive to the user, but… The bad performance of the LotusScript code was nawing at me… 

After a murky night of coding I came up with the following:

Option Public
Option Declare
Sub Initialize
	Dim s As New NotesSession 
	Dim db As NotesDatabase 
	Dim vRequest As NotesView
	Dim vMatchVacancy As NotesView
	Dim veRequest As NotesViewEntry 
	Dim veMatchVacancy As NotesViewEntry 
	Dim rowIds As String
	Dim key As String
	Dim i As Integer
	Dim count As Long
	Dim hasEmptySlots As Boolean
	
	Dim navMatch As NotesViewNavigator 
	Dim navRequest As NotesViewNavigator 
	Dim ve As NotesViewEntry
	
	On Error GoTo handler
	
	Set db = s.Currentdatabase

	Set vMatchVacancy = db.getView("vMatchVacancy")
	Set vRequest = db.getView("vRequest-list-match")
	
	Call vRequest.refresh()
	Call vMatchVacancy.refresh()
	
	Set navMatch = vMatchVacancy.createViewNav()
	Set navRequest = vRequest.createViewNav()
	
	count = vMatchVacancy.Allentries.Count
	i = 0
	
	' do not do AutoUpdates
	vMatchVacancy.AutoUpdate = False
	vRequest.AutoUpdate = False
	
	' enable cache for max buffering
	navMatch.BufferMaxEntries = 100
	' if we are not interested in the number of children, we can go a little faster
	navMatch.EntryOptions = Vn_entryopt_nocountdata
	

	Set veMatchVacancy = navMatch.GetFirst
	
	Print "content-type: text;charset=utf-8;"
		
	While ( i <  count )  
		hasEmptySlots = False
		key = veMatchVacancy.Columnvalues(0)
		
		Set veRequest = vRequest.Getentrybykey(key, True)
		
		If(veRequest Is Nothing) Then
			Print  rowIds & veMatchVacancy.Columnvalues(1) & ","
		End if
		
		Set veMatchVacancy=navMatch.getNext(veMatchVacancy)
		i = i + 1
	Wend

	
exitSub:
	Exit Sub 
	
handler: 
	MsgBox db.filepath & "agentMatchVacancys - " & Error & Chr(13) + "Module: " & CStr( GetThreadInfo(1) ) & ", Line: " & CStr( Erl ) 
	Print Error & Chr(13) + "Module: " & CStr( GetThreadInfo(1) ) & ", Line: " & CStr( Erl ) 
	
	Resume exitSub 
	
End Sub

The big difference here is the use of the NotesViewNavigator. When using the NotesViewNavigator object you have the opportunity to use it's cache – "BufferMaxEntries". I set it to 100 in my case as the view will show no more then 100 rows at a time. I also set the EntryOptions to "VN_ENTRYOPT_NOCOUNTDATA" as I have no parent/child relationship in the view.

All in all the the running time of the agent went from 4000ms to 25ms! Pretty darn impressive if anyone were to ask me!

 

This technique is nothing new, but the performance gains are so huge I thought it's well wort repeating.

I was heavily influenced by this article: "Fast Retrieval of View Data Using the ViewNavigator Cache – V8.52" and I highly recommend you check that out for more details.

 

[EDIT]

After re-running the performance tests in my local test environment I've "only" managed a 200% increase in performance. Beware, YMMV….

5

XPages – How to get a proper JavaScript debugger in XPiNC!

Posted by:

The low down: Download FireFox 5 + FireBug 1.8.4 and BAM! Instant CSJS debugger!

Yup! It’s basically that simple (for once). Read on for the gory details…

In one of my client projects I had the opportunity to work with XPages in the Notes Client, or XPiNC for short. Being a developer with almost 20 years experience I take “limited pleasure” in developing for the Notes client. My opinion is that you’re too restricted in what you can achieve front-end and graphical layout is unmistakably Notes – in a bad way. IBM Notes has it’s benefits – like you only have to worry about the shortcomings of one client, where as web clients have a legion of different vendors and versions. Sometimes even the same vendor is incompatible with it’s own versions! Yes – I’m looking at you Internet Explorer! But still, the benefits of web based development outweighs the negatives, at least for me.

But, hey! We have a new kid in town: XPages! Who’s supposed to run in the Notes client, more or less without modification…

“Wow! What a totally amazing, excellent discovery!”-Wayne Campbell

 

Excellent! Or – It could have been

XPiNC uses a browser to render your XPage inside the Notes client. We have been able to do parts of this for years, by utilising an embedded browser control in the Notes client:

Domino Designer – Form – Create / Object / Control – “Microsoft Web Browser”

You can see in action here, from an application I did a while back. We’re jumping straight into the action at 3:04 showcasing the embedded  “Microsoft Web Browser”-control in an ordinary Notes form, no XPages as far as the eye can see!

video demo of the "Microsoft Web Browser"-control in action

Video demo of how an embedded web browser control can interact with a Notes client, without using XPages

Yes – Yes! I Know! It doesn’t have the full potential of XPiNC, like offline support, field level encryption and so on. But still, it usually impresses the “general population”. You might notice that the performance of the web part of the GUI isn’t stellar? It’s because the client used IE7 which is “less then great” (to put it kindly) at performance in general and JavaScript in particular.

 

Speaking of old browsers

Anywho! Where was I…? Yes! This could be really great news – the ability to run XPages in the Notes client. But it has some shortcomings. The browser we’re stuck with is something called a “XULRunner”, more about that in a bit. The version of your embedded browser differs depending on the version of IBM Notes in use. In my case: IBM Notes 8.5.3FP1 UP1 translates to R5.0 of XULRunner. One way to check what version your particular installation is using is to run a JavaScript snippet: window.navigator.appVersion on an XPage in your environment. Now, there’s a gazillion different ways to achieve this. Well, maybe not a gazillion exactly – but there abouts. I will demonstrate a particularly cumbersome way, just because I can! (And you will see some added benefits to your development environment in the process).

 

Getting FireBug Lite

When I first started dealing with XPiNC I found that you can set some params in the XSP.properties file to enable some version of FireBug Lite:
xsp.client.script.dojo.djConfig=isDebug:true

That’s one way of doing it. But you’re stuck with a really old (and ugly!) version (surprise! NOT!) A much better way is to inject the FireBug addOn thru an Eclipse plugin. This way, no other developers will be bugged (pun intended) by the debugger and you can always enjoy the latest version of FireBug, regardless of what IBM seems fit.

So, without further ado, I present the excellent work by Mr Karsten Lehman: XPiNC app development tool

 

XPiNC front-end performance

Once that is over and done with, you can run my earlier JS snippet:  window.navigator.appVersion – In my case that would return “5.0 (Windows; sv)”.

– Ok, great! We now know that you’re running R5.0 of something called a “XULRunner”. That’s neat and all! But why should I care?

Well, because XULRunner 5.0 is in all useful purposes equivalent to FireFox 5.0!

– Wohoo! Sweet! But.. But? Isn’t that like reallllly old?

Yes, yes it is. It was released back in the day: 21 of June 2011. 14 releases, or almost two years ago (That’s like 20 “web years”). The latest version, at the time of this writing, is R19.0!

(Earlier version of IBM Notes uses the XULRunner equivalent of Firefox 3.6.x)

HTML5 support

Below is a comparison between the HTML5 capabilities between the different versions of Firefox currently used in IBM Notes vs the latest release of Firefox available:

Comparing HTML5 capabilities Firefox browser versions

[Click the image for the full comparison.]Comparing the HTML5 capabilities of the different versions of Firefox

As you can see the capabilities aren’t great, but whether it’s a real problem is entirely up to the application being developed. Put simply, if you’re not taking advantage of the capabilities in HTML5 (you should!) then this won’t be a problem.

To get some ideas, regarding the benefits of using HTML5, I recommend the site HTML5Rocks.

CSS3 support

But the limitations doesn’t end there I’m afraid. I’ve included a comparison for CSS3 support below. Showing R3.6, R5.0 and R19 in that order. (Click the image for the full comparison! But be warned, it’s BIG!)

Comparing CSS3 support across Firefox versions

This is not an exhaustive comparison, but should give a good indication.

If you click the image, you will be painfully aware of small nuances that will plague your road to the pixel perfect heavens of stardom!

JavaScript performance

If that wasn’t bad enough, the JavaScript performance is about 200% faster in Firefox 19 compared to Firefox 5. (Haven’t been able to test Firefox 3.6, but do expect it to be quite a bit slower.)

Running the browsers thru the ECMAScript testing page (click here to test it yourself) will make you even more depressed. Firefox 3.6 fails in 4247 tests, Firefox 5.0 fails 282 and Firefox 19 in 170. Granted that Firefox 5 scores pretty good, but for instance it doesn’t support the very common DOM operation parentElement. Makes you wonder what else it has in store for you programming endeavours doesn’t it?

Basically, what all this boils down to, is that to keep your XPages compatible with XPiNC you have to limit your webpages to the old standard that particular version of Firefox supports (dragging newer browsers down), or support two different versions of your XPages. Not a very appealing proposition either way.

I expected IBM Domino 9 to update the XULRunner, but no luck there. At least the public Beta 1 is still running R5.0 of XULRunner. I’m not expecting this to change for the released version, which is too bad.

Still some good news

If you’re a “Copy / Paste”-developer – who sticks with the default widgets provided with XPages,  then the above probably won’t cause you much headache and I’m afraid you’ve read most of this in vain. Because XPages in combination with Dojo will make most of the differences go away and the ones that are left might be tolerable to you.

But if you like to not only push the envelope, but to kick the crap out of it! Then the above will be the cause of some major grief and sleepless nights.

Hopefully you can limit some of the pain, revelling in the fact that you can do your front-end debugging using all the glory of FireFox 5 instead of mocking about with the embedded XULRunner client in the Notes client. This includes installing a big fat and juicy version of FireBug 1.8.4 in FireFox 5, no more debuggers on a diet for you!

You can download FireFox 5 here and FireBug 1.8.4 here.

Yet to come

I plan a follow up post where I share my experience developing for XPiNC, like potential pitfalls and how to circumvent those.

Keep watching this space!

In the meanwhile you can follow me @JBoive &| Google+

0
Page 1 of 2 12