Java and XPages

I still meet Domino developers who want to use XPages in the way IBM told them how to use it. Completely wrong I would say. Now that you have to chance to learn Java skills – EMBRACE IT!

Okay the other way around is sometimes a pain in the ass and complete examples are scarce but it gives you a better way to control your application and it’s behavior. After a while you get better understanding of the underlying technique and there is nothing wrong with that.

At the end it is mostly about creating, reading, updating and deleting stuff.

So for those developers I have setup a simple presentation to get a better understanding of JSF, Java and XPages:

Advertisements

Threads and Jobs on release 9

On OpenNTF you can find a project called Thread and Jobs:

This project contains samples showing how to create threads and Eclipse jobs from XPages to run longer taking operations asynchronously without blocking the XPages user interface or to run scheduled tasks.

It turns out that there have been updates in Release 9 in the ThreadSessionExecutor class and no longer a Status object is returned.

So if you want to have the example application working on your Domino 9 server you should remove the Status/iStatus library import and change the return type from Status to Object as followed:

/*
* © Copyright IBM Corp. 2012
*
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.openntf.samples.thread;

import java.util.Date;
import com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.Session;

/**
* Thread sample
*
* @author priand
* @author Niklas Heidloff (simplified sample)
*
* Updated 2016-10-18 Patrick Kwinten
*
*/

public class ThreadSample {

private static MyThread myThread;

public static boolean isRunning() {
return myThread != null;
}

public static void startThread() throws NotesException {
if (myThread != null) {
stopThread();
}
try {
synchronized(ThreadSample.class) {
if (myThread == null) {
myThread = new MyThread();
myThread.start();
}
System.out.println(“Thread started”);
}
} catch (Throwable t) {
t.printStackTrace();
}
}

public static void stopThread() {
if (myThread != null) {
synchronized(ThreadSample.class) {
if (myThread != null) {
myThread.stopRequest = true;
myThread = null;
System.out.println(” >> Thread stopping”);
}
}
}
}

private static class MyThread extends Thread {
boolean stopRequest;
private ThreadSessionExecutor < Object > executor;
MyThread() throws NotesException {
this.executor = new ThreadSessionExecutor < Object > () {
@Override
protected Object run(Session session) throws NotesException {
try {
System.out.println(” >> Thread running”);
Database db = session.getDatabase(null, “ThreadsJobs.nsf”);
if (db != null) {
if (!db.isOpen())
db.open();
if (db.isOpen()) {
System.out.println(” >> Database opened: ” + db.getTitle());
Document doc = db.createDocument();
try {
doc.replaceItemValue(“Form”, “ThreadTest”);
doc.replaceItemValue(“DateTime”, session.createDateTime(new Date()));
doc.save();
} finally {
doc.recycle();
}
}
}
} catch (Throwable ex) {
ex.printStackTrace();
}
if (!stopRequest) {
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
//return Status.OK_STATUS;
return “probably OK”;
}
};
}

public void run() {
while (!stopRequest) {
try {
executor.run();
} catch (Exception ex) {}
}
System.out.println(“Thread left”);
}
}
}

I have not yet managed how to fix the JobScheduler class…

User Information class

For a project I needed to check which rights a user has in a database and on documents. The UserBean in the Extension Library did not seem to match my needs since that the rights of the current effective user against the database from which the code is called. In my case the documents reside in different databases than the one serving the Xpages.

Second stop was the UserBean class written by Oliver Busse. This allows me to change the effective username againt a given name.

Name name = session.createName(“a string here”);

The same principle goes for the database.

this.aclLevel = session.getDatabase(“a string here”,”a string here”).queryAccess(this.userNameCanonical);

The aclPriviliges are no part of the original code so I added something as followed:

public final List<String> aclPriviliges = new ArrayList<String>();

if ((accPriv & db.DBACL_CREATE_DOCS) > 0){
if (!aclPriviliges.contains(“DBACL_CREATE_DOCS”)){
aclPriviliges.add(“DBACL_CREATE_DOCS”);
}
}
if ((accPriv & db.DBACL_DELETE_DOCS) > 0){
if (!aclPriviliges.contains(“DBACL_DELETE_DOCS”)){
aclPriviliges.add(“DBACL_DELETE_DOCS”);
}
}

I registered my class as a Managed Bean and I invoke it from the beforepageload event:

<xp:this.beforePageLoad><![CDATA[#{javascript:UserInfo.init(“location of my nsf”,”Ja user name here”);}]]></xp:this.beforePageLoad>

With this I can use it in the same way Oliver demonstrated in his snippet. But I can also check the acl Priviliges:

<xp:div>
<xp:label value=”ACL Priviliges:”></xp:label> 
<xp:label value=”#{javascript:UserInfo.aclPriviliges}”></xp:label>
</xp:div>

Next I wanted to check if a user can edit a document or not. This is not that easy as it might seem. This code is what I took as starting-point. It became this piece of code:

public boolean canEdit(String docId){
boolean canEdit = false;
NotesContext ctx = new NotesContext(null).getCurrent();
Session session = null;
session = getCurrentSession();
try {
Database db = session.getDatabase(“”, this.activeDb);
Document doc = db.getDocumentByUNID(docId);
if(null != doc){
canEdit = ctx.isDocEditable(doc);
}
} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return canEdit;
}

Unfortunately I cannot set the username, so it runs against against the effective username 😦

I tried to achieve the same functionality with the lock function for documents (which you have to enable on database level) but it fails. Even a given user with Reader access was able to lock a document (name added to $Writers field)

public boolean canWriteDocument(String docId, String userName) {
boolean canWrite = false;
Session session = null;
session = getCurrentSession();
try {
Database db = session.getDatabase(“”, this.activeDb);
if (db.isDocumentLockingEnabled()) {
//Document locking is enabled
Document doc = db.getDocumentByUNID(docId);
if (null != doc){
if (doc.lock(userName)) {
canWrite = true;
doc.unlock();
}
}

} else {
//Document locking is NOT enabled
}

} catch (NotesException e) {
// fail silently
e.printStackTrace();
}
return canWrite;
}

I assume I am doing something wrong but I am not sure what. If you happen to know what then drop a comment.

Happy development 🙂

Add 20 years of experience to your workforce

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !

Lotuscript to Java Beans

It seems that video tutorials / webinars have become the standard in education. Probably because video seems to be considered as one of the most trustworthy source of information. The less positive effect of video tutorials is that they (still) take time.

During a trip lately I was able to watch the excellent Lotuscript to Java Beans webinar, presented by Tim Tripcony.

Below you find screenshots of moments I thought were most interesting:

00-35-37

00-39-34

00-41-28

00-46-42

00-50-13

00-53-01

00-56-06

00-57-16

Go watch that show if you have not already!

Job Wanted

Looking for a creative brain? Choose me!

job-wanted

Zähme den Tiger – Java entwicklung in Notes & Domino

Introduction

Today I read this presentation by Bernd Hort held at EntwicklerCamp 2012. Judging fromthe different presentations this sounds like a excellent conference!

This was a nice opportunity to rehearse my German. In case your German is not so good I recommend to listen to a couple of albums of these guys and you will do just fine =)

The presentation can be divided into 2 parts:

  • A general introduction to the Java language.
  • Java in Notes & Domino in details.

Introduction Java language

A nice introduction to the language. More details I found in the jumpstart Eating the elephant.

Java in Lotus Notes & Domino

This section is divided into:

  • Applets
  • Agents
  • Servlets
  • Standalone applications
  • XPages
  • Plugins
  • Other

Applets

If you are interested in writing applets The View has published plenty of articles about this.

Agents

  • Similar to LotusScript agents.
  • Only back-end documents.
  • Notes:
    • Scheduled agents.
  • Web:
    • WebQueryOpen / WebQuerySave.

Also here check The View knowledge database to find articles on Java agents.

Servlets

Also a walk through memory lane…

  • Advantage in comparison to Java agents is than once the servlet is initiated the second call is much faster.

Standalone applications

Read: Java access to the Domino Objects (DeveloperWorks)

XPages

Lots of examples of Java with XPages here (setup folder structure, import jar files, notes.ini variables, writing Java classes from Package explorer…)

Other

  • Web services
  • OSGI tasklets ( Java based server tasks)

Summary

Another great presentation on Java in Notes & Domino. However most parts are also discovered in the other presentations I described earlier. Nevertheless recommended to read (if you like German).

AD104 Intro to Managed Beans (Russel Maher, MWLUG 2012)

Introduction

This presentation was not on my initial ‘to-study list’ so I will add it there. The presentation was held by Russel Maher at the MWLUG 2012.

Not surprisingly this presentation has quiet some familiarities with the presentation Improving XPages Application Performance with Managed Beans (Russell Maher, The View Advanced Xpages 2012).

Same presenter, similar topic.

Beginnings

Why use beans, managed beans and Java in your XPage projects:

  • Makes your applications run faster.
  • Reduces app maintenance efforts.–
  • Improves reliability.
  • Makes you a stronger developer.
  • Enhances your professional skills.

Complexity

Arguments why objects are sometimes better:

  • A user can have more metadata than just their name and roles.
  • A “document” might actually be comprised of multiple records.
  • An “environment” might be comprised of multiple databases.

Reduce complexity by embracing complexity:

  • Managing a large number of scoped variables in your app.
  • Dynamic visibility of scoped variables.
  • Progressive disclosure of scoped variables.

Requirements of a Managed:

  • Java class.
  • No-argument constructor.
  • Expose properties/fields through getters/setters.
  • Serializable.

Persistance

Sometimes data needs to stick around for a while:

  • “Data” can be a number or a complex object.
    • Session scoped.
    • A session is generally there until the user shuts down the browser.

Persistence allows you to know what the user did “before”

  • They saved a document.
  • They saved as draft/complete.

Beans can be scoped to application, session, view, request or none.

Managed Properties

Sharing data between beans:

  • Representing complex objects typically results in a “logical normalization” of data.
    • You generally will include all of the data about an object with that object.
    • You generally will not duplicate that data into other objects.
  • You want to pass data from one bean to another.
  • You need to read some existing data in another bean from your current bean.

Options for sharing data across beans:

  • Using variable resolvers:
    • Accessing other beans through the session map.
    • See: Persistence
  • Using managed properties:
    • One bean is a property of another bean.
    • Configured in faces-config.xml.
    • Object declared within “container” bean.
    • At run time the managed property is “injected” into the container bean.

Defined in Faces-config.xml:

 

How to use the managed property:

 

 

Managed property setter:

 

Tips

Use proper scopes and load order

  • Use the longest scope you need that will work:
    • Issues with viewScope serialization?
      • -> Use session scope.
    • Only need the bean for a single request?
      • -> Request scope.
    • Don’t need the bean to persist at all?
      • -> None scope.
  • Every bean must be called before it can be used.
    • If you try to inject Bean B into Bean as a managed property and Bean A has not been instantiated yet…you got problems.
    • If Bean A errors out but is a managed property of Bean B…you got problems.

Use Java UUID to get unique numbers

  • Designed to give universally unique numbers.
  • Beats inventing your own mechanism if all you need is a unique number.

 

 

Summary

Another great introduction on managed beans, especially if you didn’t get a hold on the Improving XPages Application Performance with Managed Beans from The View conference.

I haven’t taken a look at the example database, which was demonstrated during this presentation but that is something I will surely will when returning back to the office on Monday.

That’s it for this week. It has been a great 5 days of Java in Xpages. For next Monday I schedule ‘Zähme den Tiger – Java-Entwicklung in Notes und Domino‘. Looking forward to rehearse my German skills!

AD102 – Caffeinate your XPages with Java (Jeremy Hodge, MWLUG 2012)

Time for another step in my road ahead. This time I have studied Jeremy Hodge’s presentation at MWLUG 2012. As promised Jeremy will demonstrate how to inject Java in XPages application.

Getting started with Java in Designer & XPages

Java Design element in DDE 8.5.3:

Roll out your own project structure via Package Explorer Eclipse view:

You can customize your Java perspective:

  • Should reside in the WebContent folder.

What is a package?

  • A way to organize source code modules by using a namespace to prevent class collisions.
  • Provides some access control on what is accessible between classes.

Package

In the Package Explorer right click your source folder, select New > Package.

Naming conventions for a Package:

  • Everything lower-case.
  • Reverse domain name; Project . Sub-Project
    • e.g. com.zetaone.mwlug.ad102

Java class

In the Package Explorer right click the Package, select New > Class.

Naming conventions for a Java class:

  • UpperCamelCase class name.

The new empty class is created & opened in the workspace.

 

Access levels to methods:

  • Public:
    • Any other class, in any package can access the method or member field.
  • Private:
    • Can only be accessed within the same class.
  • Protected:
    • Can be access by the current class, sub-classes, or any other class in the same package.
  • Blank:
    • Can be access by the current class, and any other class in the package, but not any sub-classes (unless they are in the same package).

Access Java packages via import e.g. import java.util.Date

Managed beans

Bean

Nothing more than a simple Java class.

Managed bean

A Java Class that conforms to a specific set of requirements so that the XPages runtime can create / discard / etcetera our beans for us when we want to use them. In other words it manages our beans for us.

Three things required for a managed bean:

  1. Argument-less constructor.
  2. Serializable.
  3. Uses Getters / Setters to retrieve / store information.

Constructor

A method:

  • With no return type.
  • Has the same name as the class itself.
  • Does not take any arguments.

public class HelloWorld {

public HelloWorld(/*SEE NO ARGUMENTS HERE*/) {
// Do initialization here if you need to…
}
}

Serialization

The process by which an instance of a class is stored in a form that can be written to disk, the network, etcetera and then converted back into a full in-memory instance (save/restore state).

In most cases basic classes can be serialized by implementing Serializable and adding serialVersionUID.

 

implements Serializable

This is called an interface. An interface is a predefined set of procedures for transmitting data between different objects.

Serializable defines 2 Methods:

  • writeObject
  • readObject

serialVersionUID tracks what version of this class is so that objects serialized with one version are not de-serialized into a different, incompatible version.

private static final long serialVersionUID = 1L;

  • static:
    • The declaration belongs to the class, not the instance, and all instances of the class share the same serialVersionUID instance (not value) and it is stored with the class.
  • final:
    • Once it is assigned, it can’t be assigned again – Must be assigned when its declared, or in the constructor.
  • 1L:
    • The “L” makes the 1 and long integer (64bit), rather than the default 32bit integer.

Getters / Setters

Use getters / setters to retrieve or set values inside your class instance.

Declaring a managed bean

  • Modify faces-config.xml located in WebContent/WEB-INF.
  • Set the Name, Class, and Scope of the Managed bean.

Usage within Xpages

Use the managed-bean-name to reference the class. Expression Language (EL) converts “helloWorld” to getHelloWorld() and “helloWorldDateTime” to getHelloWorldDateTime() when reading the value from the bean.

 

But we also defined a setHelloWorld() method. How do we use that to store a value back into our instance?

  • If the component that you bind to your class member is read/write (ie a text box), it will call the setter to update the new value automatically. You don’t have to do anything else!

EXCEPT: Since we are now storing data in the instance that we want to stick around between requests, we need to update our faces-config.xml to set a different managed-bean-scope, such as view.

 

 

 

 

 

 

 

 

 

 

 

 

 

After refresh:

 

Reading & Writing Notes Data in Java

Similarity between reading / writing Notes data in LotusScript, Server-Side JavaScript and Java.

 

Tips, Tricks, & Gotchas

Compare objects

If you want to compare two objects, the objects need to have a .equals() or .compareTo() method.

If (string1 == string2) {
// This is (almost) never true
}

For objects, the == checks to see if the left and right objects are the same object (same address in memory), not if the string has the same content.

If (string1.equals(string2)) {
// Now we’re cooking…
}

There is also an .equalsIgnoreCase()

Getting SSJS Common Instances in Java

SSJS is a scripting language, so several objects are pre-defined and immediately available to you (ie database, session, sessionAsSigner).

In Java, you need to get the variable resolver, and resolve those variables to get at those objects.

 

There is a set of helper functions in a JSFUtil class that Jeremy as posted on OpenNTF In a project called mypic (http://xpag.es/?mypic)

Security

At some point you are likely to want to use a 3rd party class. You’ll put the JAR file in your NSF, add it to the build path, and you’ll think life is grand, until.

NoClassDefFoundError

Two main reasons you will get this error

  • Unresolved Dependencies.
    • You didn’t add all the JARs you needed to.
  • The Security Manager is telling you to take a hike, it doesn’t trust that “type” of code in an NSF.

Edit your $INSTALL\jvm\lib\security\java.policy file and grant all permissions to all code.

Serialization, Recycle, and Notes objects

You can not serialize lotus.domino.* classes, ever, AND they WILL get recycled on you – so having them as class members is dangerous!

Biggest reason is recycle(). Recycling is unique to the Notes/Domino objects because the java objects are a wrapper around the C API objects.

Two ways to get around it.

  1. Only deal with the Notes objects when you have to “go to disk” – i.e. load document, save document, read from a view, etc.
    1. Do it all locally within your method, store the contents you read in class members, then discard all Notes objects immediately.
  2. Mark your Notes objects as “transient”, then implement a method to return the cached object.
    1. In that method, check to see if the object is valid, and if so, return it, otherwise, get it again.

Recycle

General rules:

  • You should recycle anything you open when you no longer use it (but one-off documents or databases won’t hurt you too bad) … improves scalability.
  • Anything you open in a loop, recycle before the next loop – or you’re prone to crash w/ “Out of Memory” errors – DON’T Recycle a session, or anything you get from a resolveVariable() call

Summary

This presentation is another great step learning Java especially in the XPages environment. In the last section of the presentation, “The Fun Stuff”, Jeremy goes into detail describing an example of what you are capable of using Java in XPages. This section is a bit out of my head, right now.

I thank Jeremy for sharing the presentation! I noticed also a second presentation Jeremy held at the MWLUG “Introduction to managed beans“. I add this also to my ‘to-study’-list.

 

 

Improving XPages Application Performance with Managed Beans (Russell Maher, The View Advanced Xpages 2012)

Introduction

This post is part of my road to more Java in my XPages projects. The next presentation was held at The View – Advanced XPages workshop early 2012 in Amsterdam. I am a bit reserved what I can and cannot share. The presentation is not on-line available so I will re-create all screenshots. Hopefully this abstract won’t trigger someone from their legal department to contact me =)

Main topics:

  • Java Design element.
  • Managed beans.

Java design element

This design element is new in 8.5.3 and makes using custom Java much easier in XPage application:

  • Your class will be added automatically to the project build path.
  • It allows you to work with Java without going via the Package Explorer view in DDE.

What allows this Java design element? You can create:

  • A class or package of classes.
  • Interface; a set of required methods in order to “implement”.
  • Enum; set of constants in Java.

Java class

  • A POJO (plain old java object) is created.
  • Representing a single Java class.
  • Multiple Java classes can be packaged together.

Some rules:

  • Package name and class name need to be defined during creation.
    • Package name typically are domain names in reverse:
      • e.g. com.wordpress.bildr
        • Will be displayed in DDE as com/wordpress/bildr/classname.java

The result in DDE (Code\Java view):

The result in the Java editor (DDE):

The result in the Package Explorer Eclipse view:

How do you call the Java class?

  • From any server-side JavaScript.
  • From other Java classes within your application.

Example calling one class from another

SecondClass that returns a string:

package com.wordpress.abc;

public class SecondClass {

public String printMe(){
return “hello world”;
}
}

FirstClass that creates a SecondClass object and calls the printMe() method in it:

package com.wordpress.abc;

public class FirstClass {

public String callMe(){
SecondClass sc = new SecondClass();
return sc.printMe();

}
}

Server-side JavaScript that creates and uses a FirstClass object:

Output

You can create output to log.nsf via:

  • print(“”)
  • System.out.println(“”)

Java Interface

An interface defines a set of methods that can be “implemented” by Java classes. You can structure your code more via an interface.

Java Enum

An Enum defines one or more constants that you can use in your Java code.

  • declared public
  • defines constants
  • declares a private constructor
  • declares any public methods

Java Bean

A standalone piece of Java code constructed in a way that it can easily be consumed by other Java code.

Rules

  • A bean is a Java class with a no-argument constructor:
    • The constructor is the method with the same name as the class.
  • A bean usually has some properties for the class itself.
  • “getters/setters” are used to access bean properties.
  • Getters/setters are named to match their associated properties
    • These methods must match.
      • Example: If the property called myAge, the method must be called getMyAge.

Managed Beans

A managed bean is a Java bean but is not associated with a visual control.

A managed bean follows the standard bean requirements:

  • No-argument constructor.
  • Properties exposed via public getter / setters.

A managed bean needs to be on the build path of your application. The Java design element takes care of this. Alternatively go via the Package Explorer and create a source
folder in the project to add code there.

You need to register a managed bean to make it well-known within your application. You do this in the faces-config.xml file.

Configuration settings

  • Name:
    • Reference to the bean from other code.
  • Class:
    • Java class of the bean.
  • Scope:
    • Application, session, view, request or none.

<managed-bean>
<managed-bean-name>carBean</managed-bean-name>
<managed-bean-class>com.wordpress.myCar</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

When the bean has been registered you can use it from different places.

From other Java code

myCar mc=new carBean();

From server-side JavaScript

carBean.buildFromField(currentDocument.getDocument())

Via Expression Language

#{carBean.isSporty}

Serialization

The ability to store the state of a Java object for later use. Serialization can improve the performance of Java. It is therefore recommended that beans implement Serialization.

Screenshots

sessionMap

The sessionMap object can be used to pass data between managed beans.  You can put data into and read out the sessionMap object.

Typical scenario:

  • Bean X puts data into the map.
  • Bean Y reads the data from the map.

Methods:

Bean injection

When one managed bean is a managed property value of another managed bean, the managed bean instantiates itself.

<managed-bean>
<managed-bean-name>carBean</managed-bean-name>
<managed-bean-class>com.wordpress.myCar</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>imagesDB</property-name>
<value>#configBean</value>
</managed-property>
</managed-bean>

Scope

You need to make sure the injected bean lasts at least as long as the dependent bean so they accommodate each other!

Summary

This post is just a small abstract of the presentation so if you want a clear understanding of the topic I recommend everyone to participate in an XPages bootcamp organized by The View. I am sure that in 2013 they will visit the old continent another time.

The presentation brings me a step further into using Java in XPages. Especially the managed beans section is well explained and some items are beyond the first steps I will take implementing Java.

You can start using Per Hendrik Lausten’s blog post as a starter to get more into managed beans. Jeremy Hodge also covers the topic here.

So far the presentations learned me about Java fundamentals, the Java design element, the Package Explorer view in DDE, working with Managed Beans and importing third party libraries.

The next step for me would be either to look more into the technology or to start looking at some real world code examples. I found one example I like: Log data changes using beans and the DataObject interface.

BP118 Using Java to build applications fit for the enterprise (Chris Connor, Lotusphere 2012)

Introduction

Last evening I enjoyed another opportunity to learn Java in Xpages a bit more. This time I took the BP118 presentation because it jumps directly in the area I am working daily in: XPages! After reading the presentation one word was on my mind: Managed Beans.

Managed Beans

  • POJO – configured with getters / setters.
  • Implements “Serializable” (so XSP can read / write from disk).
  • Can be scoped:
    • Request.
    • View.
    • Session.
    • Application.
  • Very useful for:
    • Providing universal access to common lookups.
    • Providing “states” in an application.
      • e.g shopping cart / “one to many” tables.
    • Calling your Java libaries easily
      • BeanName.doMethod() or BeanName.someproperty
        • e.g. uk.bssuk.net.domino.data.ObjectName.doMethod()

Important!

Do Not Try to scope Domino Objects. They are C++ Objects and are subject to unpredictable garbage collection (eg NotesDocument, NotesDatabase).

Instead work with primitive types and objects such as String, ArrayLists, HashMaps etcetera. E.g. where a document is required use the UNID instead (String).

Use cases

The presentation describes a couple of use cases where managed beans are used.

Use Case 1 – Lookups

Most databases have lookup lists (e.g. keywords). You should decide on which ones are common:

  • Keep the common lookups in a library for sharing across all databases.
  • Application specific lookups can reside in a class/classes.

Goal from Expression Language / SSJS:

  • Simple call syntax e.g. “Lookup.Locations”.
  • Cached for the appropriate Life Cycle (good for performance):
    • Session.
    • Application.
    • Request.
    • View.

Steps to define a managed bean:

  • Find and Edit the Faces-Config.xml file.
  • Go to the Java Perspective in DDE.
  • Package Explorer.
  • Register your bean by adding XML Contents as shown in the image:

 

Personal comment: Too bad that the code for the class is not included. I am not sure if a sample database is available somewhere???

A simple call to the bean will get you a cached version of whichever property we want:

  • ArrayLists.
  • Strings.
  • Objects.
    • Not Domino Objects!

Example of a call:

  • More efficient than lots of @DbLookups everywhere.
  • Can deploy in an OSGI library for sharing over all your databases.

Use Case 2 – Line Items

Many applications have 1-to-many tables:

  • Order line items.
  • Expenses line items.

Managed Beans can help with this:

  • Provide a flexible structure for modelling.
  • Abstract out data.
  • No need to worry at early development:
    • Could be response documents.
    • Related documents by key.
    • Relational database table(s) data.

Use a classic MVC

Create a controller class for managing the POJO objects.

  • Adding.
  • Removing.
  • Updating.

 

  • POJO objects are real life objects (the line items).
  • Controlled by the controlling class.
  • The objects are then “written to disk” as appropriate by classes performing data operations.

Steps to define a managed bean (similar as in Use Case 1):

  • Find and Edit the Faces-Config.xml file.
  • Go to the Java Perspective.
  • Package Explorer.
  • Register your bean by adding XML Contents as shown.

 

Example: Code for the PersonController class:

 

What we are doing:

  • ArrayLists for containing Person Objects.
    • An arraylist is bound to a repeat control.
    • Methods for adding / removing Person Objects.
  • When the save button is pressed these objects are “written to disk”.

Use Case 3 – Export to Excel

Personal comment: I guess there are 3rd party libraries available that do better in creating Excel files…

Use Case 4 – Generic workflow process

Nice real world scenario however the code is cut into many pieces and therefore it is hard to follow / see the whole picture. Sample code would do magic here.

Summary

This presentation covers more the aspects I am working  daily with XPages. Too bad this presentation has only 51 slides and is therefore very compact. It would be great if a “Jumpstart” session will be made from this presentation at Connect13.

Getting hold on the example code would also be beneficial for learning Java and testing Managed Beans in real world XPages application.

JMP102 – Eating the Elephant A Java Jumpstart (Paul Calhoun, Lotusphere 2012)

Introduction

The title reflects also a bit of the presentation. The presentation contains 162 slides so you better prepare yourself for a long journey.

Here a summary of the lessons learned. I divided the presentation into categories.

Section Java language fundamentals

A lot of focus on this. Not so much news here.

Section Java Domino Objects

  • Only implements the “Back End” objects.
    • Exposed via:lotus.domino.*
  • No Notes Client UI access.
  • You (the Domino Developer) already know 98.67 percent of all of the Java class names for the Domino Back End Objects.
  • Drop “Notes” from the front of the LotusScript class names equals Java class names.

LotusScript Class Name

  • NotesSession
  • NotesDatabase
  • NotesView
  • NotesDocument
  • NotesItem

Java Class Name

  • Session
  • Database
  • View
  • Document
  • Item

 

These Java Classes don’t exist in LotusScript:

  • AgentBase
  • AppletBase and JAppletBase
  • NotesError
  • NotesException
  • NotesFactory
  • NotesThread

 

  • Java has no “Variant” data type.

Section Java Agents

  • Java Agents MUST extend AgentBase
  • Java Agents MUST use the NotesMain() method as the entry point for their functional code
  • The getSession() method creates a Session object

 

  • The Default Agent Code only catches generic exceptions
  • Add an additional catch block for NotesExceptions:

import lotus.domino.*;
public class MyFirstAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
}catch(NotesException ne){
ne.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
}
}

DDE Tip Snippets Eclipse view

An overlooked feature in DDE how to store and share re-usable code, e.g. Java code.

Java in XPages

  • Java Code can be called from any Server Side JavaScript (SSJS) event in the XPage

Section Third party Java libraries

Using Third Party Java Libraries in XPages:

  • Unzip the downloaded file to an accessible drive.

Add to the Application or Deploy to the Server?

  • Access to the library API can be accomplished two ways:
    • Adding it directly to the (every) application that will be using it.
      • Not a best practice but sometimes necessary for portability or when deploying .jars to the Domino server is not an option.
    • Adding it to the Domino server.
      • Best practice.
      • It is then available to all applications that will utilize it.
      • It can be “upgraded” to the next version and then is globally available

Regardless of the choice, the code is written the exact same way.

  • This allows for deployment using either option and then changing it later

Adding the Jar to the Domino Server.

  • Library class and jar archives can be added to the xsp folder in the Domino program directory.

Adding the Jar to a Specific Application

  • The POI jar can also be added to a specific application.
  • Switch to the Package Explorer view.
  • Expand the Virtual Project folder.
  • Expand WebContent | WEB-INF.
  • If a “lib” folder already exists, add the jar file to this folder.
  • If the “lib” folder does not exist, then create the folder and add the jar file.

 

Example XAgent Code

The XAgent (an XPage with no UI design elements) code will be used by all three use cases to create the spreadsheet.

  • The code is in the beforeRenderResponse event.

Import the Needed Packages in XPages.

  • This makes the classes in the included jar file available to the SSJS code.
  • The org.apache.poi.hssf.usermodel package contains all the classes needed to create the Excel spreadsheet.

//import the appropriate java packages
importPackage(java.lang);
importPackage(org.apache.poi.hssf.usermodel);

3 Use Cases

There are three primary use cases explained for exporting Domino data to Excel:

  • All documents in a view.
  • Selected documents in a view.
  • Document collections from a query.

Summary

This session gives a good introduction of Java fundamentals, introduces Java for LotusScript developers and touches Java in XPages.

In the XPages section 3 use cases for an XAgent is explained that uses a third party Java library.

I am not sure if the code of the export use cases is available for public?