bookmark_borderspeeding up XPages execution AND development

to speed up execution you should native Java code whereever possible!!!!!!!!! (should I add some more explanation marks???????) DID YOU GET THIS

okay.. fun aside… let’s get down to the hardcore stuff:

let’s assume you created a helper class doing some nice stuff for you on your XPage (such as logging to another place than is possible with DebugToolbar)
let’s assume your Logger is in the package com.yourcompanyname.xpages.utilities

now if you want to log the action of a button within an XPage you would need to add this code:

var Logger:com.yourcompanyname.xpages.utilities.Logger = new com.yourcompanyname.xpages.utilities.Logger()
Logger.log(“your message”)

what you might have forgotten though (actually you didn’t cause you just used it: JavaScript!)

so simply create a SSJS library which you include on every page you create.

add this line:
var Logger: com.yourcompanyname.xpages.utilities.Logger  = new  com.yourcompanyname.xpages.utilities.Logger();

you can then in your button simply log the message like this:

Logger.log(“your message”)

doesn’t that save you endless typing/correcting/testing etc?

think of the SSJS Library as a “proxy” to your native Java classes!

bookmark_bordersick of adding hundres of standard validators in a huge XPage?

I am!

do they, who the hell are they anyway?, really expect you to add on 50 to 100 fields with all those clumsy interface buttons the normal validators?
examples? let’s count the steps it takes me to add a validator:
1. select the field in the XPage
2. open properties view
3. “enlarge” (or drag it upwards) the properties view (cause it’s always to slim in height)
4. click “All properties”
5. scroll down to data or click these on the first to sections:

6. click on the “validators” which makes some equally small buttons visible
7. click the plus button to add a validator:

8. select the validator you want to apply
9.-x. add the required property values

Now repeat that for about 50 or more fields on an XPage!!! I don’t think your customer is happy to pay your for this stupid/error prone clumsy work.

well I don’t know about you.. but I want to keep as much code centralized as I can. I am such a lazy person. So I tried to follow up on our method we had in our plain old Notes framework: field validation configured via setup documents!

So I had to figure out how custom validators work. This journey also took some hours, but within a day I got all working. And this included getting the JSF phases to understand (see my other post about that topic)

Here the result:

The display will be handled by the errorMessage/errorMessages control: I tend to think of the one which is connected to the field as the “summary” message (reason is it should no distract the look and feel of your input form too much), and the ones collecting all messages as the “detail” messages, but I think its actually the other way around

Code your validator:

public class CustomValidator implements Validator {

public void validate(FacesContext facesContext, UIComponent field,
Object arg) throws ValidatorException {
String value = arg.toString();

// add here your validation conditions for which a message should be
// displayed and then
// create a FacesMessage which then will show up next to your field in
// the
String m1 = “ups something went wrong: summary”;
String m2 = “ups something went wrong: detail”;
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, m1, m2);

throw new ValidatorException(msg);
}
}

DO NOT HANDLE THE EXCEPTION!!! 
first I had a try/catch block installed.. but what happened? the messages showed up and yet the document could be save anyway!!! what a disaster… so get rid of the try/catch and let the ValidatorException be thrown and handled by the servlet engine.

faces-config.xml:

  <validator>
    <validator-id>idOfYourOwnValidator</validator-id>
    <validator-class>com.abb.xpages.framework.CustomValidator</validator-class>
  </validator>

we are done! wait!!! and how do you get this validator applied? wasn’t that the whole point? not having to repeat all those 10 steps over and over again?

well… please read this post about the phase-listener:
http://in-mood.blogspot.ch/2012/09/jsf-phases-in-xpages.html

there you add a condition which will in the beforeValidations phase add all the required validators:

add this to your phase-listener:

if (event.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) { CustomValidator v = new CustomValidator(); v.addValidators(); }

add this to your CustomValidator:
public void addValidators(){
// repeat this step (maybe in a proper loop for all fields which require the validator
// Util is a class I created with an abstract method “findComponent”, abstract such that I don’t
// have to always instantiate it whereever I use it

field = (UIInput) Util.findComponent(FacesContext
.getCurrentInstance().getViewRoot(),
“fieldNameOnTheXPage”);

// add your validator
Validator[] validators = field.getValidators();
// make sure you only add the validator once, otherwise the
// messages control will display one
// message for every roundtrip the page has done to the server!
if (0 == validators.length) {
field.addValidator(facesContext.getApplication()
.createValidator(“idOfYourOwnValidator“));
}

for single instances you can of course add it manually as well (such as for testing if it actually works:)

now there is one minor drawback in this whole process:
on my local machine the “createValidator” won’t work due to security issues.
on our test server it works, I assume it has to do with a grant * something statement I once added to the java.policy in the jvmlibsecurity directory of the program directory

update:
Add this to the grant section:
permission java.lang.RuntimePermission “getClassLoader”;

I am actually now “finetuning” the “addValidators” as I could not yet figure out how to create the “required” Validator myself such that it adds the message to the control instead of alerting it in the client!

bookmark_borderJSF phases in XPages

I was trying to setup a system to handle “validation” via setup documents
the normal validators which can be set up directly on each field would not help much (or be too much work to implement)

I first tried a simple method: isDocValid returning true/false and adding JSF Messages like following:

String m1 = “summary: ups something went wrong”;
String m2 = “detail: ups something went wrong”;
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, m1, m2);
facesContext.addMessage(field.getClientId(facesContext), msg);

I would call this methid in the querySaveEvent of the XPage, and it seemed (at least for new documents) to work well.. until I opened a document from a view, and oh wonder (maybe it’s a feature and not a bug) the querySaveDocument event was not even triggered…

That was bad news: I also had a “save as draft” button which would let the user return to the document, but if the validation then would fail?

nope.. I started looking for another way…

so I talked to a guy who has a LOT, I mean a LOOOOOOOOOOOOOT, of JSF experience.
With his help and some from my best friend (google) I did the following:

created a phase listener which logged all events (great for debugging, see those “immediate” events)
a very good article about the JSF phases can be found here:
http://www.ibm.com/developerworks/library/j-jsf3/
a MUST read for any serious XPages developer with little or no JSF experience!!

so then thanks to the phase listener I could see the how all phases process.

and now I immediately had also a way to “plugin” my custom validators properly (more on that in another post)

so here what I did for the phase listener:
Java class:

public class PhaseListener implements javax.faces.event.PhaseListener {

public void beforePhase(PhaseEvent event) {
// log your beforePhase with event.getPhaseId()
}

public void afterPhase(PhaseEvent event) {
// log your afterPhase with event.getPhaseId()
}
}

faces-config.xml:
  <lifecycle>
    <phase-listener>package.of.your.PhaseListener</phase-listener>
  </lifecycle>

now you can add simple additional code in any phase (before or after)
just use something like:

if (event.getPhaseId().equals(PhaseId.PROCESS_VALIDATIONS)) {
// run your code
}

PhaseId. (dot control space) will list all the CONSTANTS to check for any of the phases

bookmark_borderdon’t use “finally” in your Java code for XPages

since I have no started digging deeper into the XPages mysteries I want to share some of my learnings.

As most of you know: if you use Java in Lotus Notes/Domino you have to take care that you recycle the Notes objects you instantiated (session, database, document etc.)

Java has a nice feature called “finally”. If you use a try/catch block (which I do to log all errors happening, so that I can follow up and fix them) you can also add the “finally” block at the end..

It could serve pretty well for incinerating (I bought that term form some other blogger) the Notes objects…

But beware: I created a class which should be called upon the querySaveDocument event. As soon as I added the finally block the page would crash, most of the times so bad that my whole Notes/Designer went down too…

After hours (again hours!!! can you imagine what my week looks like???) putting log code moving it down one by one… until I reached the try block, nothing worked anymore…

but luck I figured: why not remove the finally block.. and miraculously the XPage could be displayed again

I don’t know what/why exactly it crashed and if you always should not use the finally block, try it.. if your system crashes, remove it and handle it in another way

bookmark_borderrequestScope mystery solved

again RTFM!!!! but hey… the FM not always tells you what you want to know!

Might that be the reason why we developers tend to NRTFM?

dunno..

anyhow… after DAYS of testing / searching (is it called googling nowadays?) / changing code and iterating a (felt) thousand times…

I finally came accross the solution how to “persist” the requestScope from one xPage to another…

First (I hope I am not wrong with this) a bit of background:

The parameters set in the requestScope would (normally) get submitted via the URL (in a GET request). As those JSF (and xPages) mostly work via POST request we (unless we use nice tools, such as the TCP Monitor in the designer!) never really see them. That’s one of the reasons so many Domino developers struggle to get the requestScope working. We cannot really debug it properly.

Thanks to TCP Monitor and a friend helping me, we finally figured:

After an xPage has been submitted and the navigation rule would redirect it to another page this redirection was a request to the client browser!

Imagine: The server tells the browser: please ask now for page xyz.xsp

And with the little background above you can understand that the server didn’t tell the browser which requestParameters it should transmit as well, alas they would be (ARE!!!) lost.

But as i said.. I did a lot of research on this and I found the following setting: (You find it under the “Package explorer” view in the designer

if you turn this feature off the server does not ask the browser for asking the new page but the server actually redirects himself to the new page and hence will preserve the requestScope values….

So you can actually have the dimmwitted example of two xPages where on one page you enter the name and submit it, and the second page will greet you with “Hello yourname” works!

I for myself will use this feature to tell my xpView.xsp (the one which handles all views in my db) will know which view it has to display after a document has been submitted (at least if nothing else has been defined)

bookmark_borderhave you ever wondered if i might be possible to make a custom control look nicer in the xPage design view?

It can be done! And it’s actually not even that complicated.

Find the instructions here:
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/16102009115724SCAEXA.htm

or read on…

there is this nice Design Definition property on all custom controls (starting 8.5.3 I think):

if you add some xPage source code to it (tip: create a new xpage the way you would like to look this custom control in the design view and copy & paste its source code here)

it will later on in the actual xPage look like this:

in this example i used is as a way to “document” some settings required to make it work properly.

But of course you could, if you have, for a company framework, also paste in a picture of a standard menu, the footer or the header of your pages.

then while designing the xPage you get a better feeling on how the page will look like later.

and it gets even better.. just read an article, that this design definition is “dynamic”, means you can actually have the custom control look different, ie. depending on custom properties you set.
Read this article: http://dontpanic82.blogspot.ch/2010/01/xpages-using-powerful-design-definition.html

bookmark_borderExtension Library installation pains

okay okay.. I know.. RTFM

but hey.. we are developers, we know what we are doing, right? 😉

How it all began:
I was first trying to install the Extension Library on my desktop manually. and of course I installed the Domino part instead of the Designer part 🙁

I then considered following those instructions here:
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Installing_the_upgrade_pack_on_Domino_Designer_and_Notes_ddxl853

but again RTFM…

I mean c’mon… can’t be that complicated.

It can!!! After 2 days of trying (installing/uninstalling both LN/FP/UpgradePack)  to get this upgrade pack installed I almost gave up.

But then I took a quiet moment and told me: one last time.

Interestingly the modules had been installed in previous attemps, only I could not load any xPage with modules from the extension library as something didn’t install 100% correctly! I always got the Error 500 command not handled exception.

With those features installed… I could finally figure out the exact filenames to check and remove manually any directory/file which was still in the mentioned (see link above) directories. If Windows 7 search would have done a better job I wouldn’t have needed those exact filenames though, maybe some of my anger goes to MS.

so here is how I found the exact names:

Files searched:
  • org.apache.wink…
  • com.ibm.domino.das…
  • com.ibm.wink…
  • com.ibm.xsp.extlib…

directories searched:

  • frameworksharedeclipsefeatures
  • frameworksharedeclipseplugins
  • datadominoworkspaceapplicationseclipsefeatures
  • datadominoworkspaceapplicationseclipseplugins
  • dataworkspaceapplicationseclipsefeatures
  • dataworkspaceapplicationseclipseplugins

So after I had figured out the names I had to look for and manually deleted them (also in the DataWorkspace and DataDominoWorkspace directory), the upgrade pack installed just fine…
yours
Michael

bookmark_borderever wondered how to toggle single-sign on feature?

If you did install the single-sign-on feature with Lotus Notes and you got it working, fine.

But what if for some reason you want to disable this feature?

And you find unluckily it’s grayed out and thus cannot be disabled?

help is around the corner…

run Notes as “Administrator”

and you happily find this feature “active” (ie. not grayed out anymore), thus you can now disable it

bookmark_borderdid you know about all those “undocumented” features LN offers?

following this link you will find a lot of really cool stuff which is hidden underneath, ie. undocumented

http://www.devinolson.net/devin/SpankysPlace.nsf/d6plinks/DOLN-8G4NBJ

IBM: please make those features “documented”!

do you personally use “undocumented” stuff in the LN world? did you ever face challenges?

bookmark_borderdo you ever read “release notes”?

it’s been a while since my last post here.

i usually don’t really read release notes, do you?

but did you know those cool features about the new table edititing possibilities in the LN8.5 client?

  • Drag column or row margins to resize
  • Drag the margins of the entire table to resize it
  • Drag the contents from one cell to another
  • Set the table width when creating a fixed width table
  • Easily insert a new row or column by holding down the Shift key and double-clicking the common border

or these ones:

  • a new Folder column in the mail All Documents view displays any mail folders that a document is in
  • From any mail view, right-click on the Trash folder and select Empty Trash.
  •  Back by popular demand, you can use red text to indicate unread documents. Click File > Preferences, and then click the Fonts and Colors preference. For the field Unread mail indication, select Plain red text. Also note that this preference provides you with an easy way to enlarge the text in the data areas of Notes, such as the Inbox and messages.
  • To select an alternate email address, when you begin typing a name, select Other email Addresses from the menu that appears. The more frequently used addresses display at the top of the list.
looking forward to more exciting features