07/14/2010

Dynamically Create vCard Download from LotusScript

Tags: LotusScript development vCard WebDevelopment

Reading Matt's entry about the content-disposition http header reminded me of a LotusScript agent I wrote recently which also uses this technique.

I have created a nice looking office locator for one of our clients which uses the Google Maps API and Dojo Toolkit to display the results. For every office you can also download a vCard which is dynamically created from a company record stored in a Notes document*. The vCard is created by an agent which is called with the UNID of the company doc in a URL parameter. The agent created the vCard text and returns it as an attachment with a custom file name using the aforementioned content-disposition http header.

Please read on for the agent code.

Download File agGetVCard.lss

08/11/2009

LotusScript.doc V2 beta is available

Tags: development lsdoc tools LotusScript

Mikkel has just published the first public beta of LotusScript.doc V2. It is a great tool for creating a documentation of all LotusScript code in a Notes application. We have been using it for many years now and have adopted the lsdoc comment style as a company standard.

I have been one of the alpha testers and I can tell you that the performance of creating the documentation is absolutely amazing. It only takes a few seconds to create a documentation of a really complex database like the mail template for example.

Now go and get it and provide Mikkel with feedback. He's been spending a lot of his spare time to create this little gem and we all can benefit a lot from his work.

05/20/2009

AJAX loading gif generator

QuickImage Tags: development
Note to self:
Self, did you ever want to have a snappy little image, to pretend activity in an AJAX web application during backend loading processes?

You can generate such images with colored background and foreground to your liking at www.ajaxload.info.

05/19/2009

Input Validation of Number Fields in Domino Web Applications

Tags: development JavaScript

In web applications Domino outputs decimal numbers stored in a Number field using the decimal separator which it deems right for the language set in the user's browser. If the numbers need to be edited in a web form, you need to make sure the users only enters valid numbers. For this, you might want to do an input validation in JavaScript to avoid unnecessary round trips to the server because of invalid numbers (being a good developer you will of course do a server side check as well, but that's not my point here).

Here's a little JavaScript function which uses regular expressions to check if a number is valid (thanks, Nicolai). It can be used for input validation and returns a boolean value. It should accept all number formats Domino accepts as well. Please let me know if you find it useful or if it needs to be improved.

The function uses two global variables containing the decimal and thousands separators.

/**
 * Check if the value of the input field is numeric and return false if not.
 * The global variable strDecimalSeparator contains the decimal separator 
 * Domino uses with the browser's locale.
 * It is used to convert and check the correct number format.
 * The global variable strThousandsSeparator contains the thousands separator 
 * Domino uses with the browser's locale.
 * @param {String} input value to check.
 * @version 1.1 build 2009-05-19
 * @author Nicolai Hess, SP Integration GmbH
 */
function isNumeric(input) {
  var strExpr = eval('/^-?\\d+$|^-?[1-9]+\\d?\\d?(\\'+ strThousandsSeparator +
    '\\d\\d\\d)*$|^-?[1-9]+\\d?\\d?(\\'+ strThousandsSeparator +'\\d\\d\\d)*\\' + 
    strDecimalSeparator + '?\\d+$|^-?\\d*\\' + strDecimalSeparator + '?\\d+$/');
	return strExpr.test(input);	
}
In oder to determine which separators Domino uses (and expects) in Number fields, I set these two global JavaScript variables in the HTML Head section of my form. Because Domino outputs numbers depending on the browser's language, we can simply extract the separators from numbers converted to text.
"<script type=\"text/javascript\">" + @NewLine +
"var strDecimalSeparator = \"" + @Middle(@Text(1,2); 1; 1) + "\";" + @NewLine +
"var strThousandsSeparator = \"" + @Middle(@Text(1000; ","); 1; 1) + "\";" + @NewLine +
"</script>" + @NewLine

03/20/2009

Clearing the Replication History Using LotusScript

Tags: development LotusScript

Let's assume we have a Notes database with documents containing reader fields. Let's also assume the reader fields contain group names. If a user has a local replica of this application it will obviously only contain the documents he is allowed to see.

When the admin adds the user to a group which allows the user see more documents in the database they might not replicate down because their modification date is prior to the last replication date stored in the replication history. In order to make these documents replicate to the user they either need to be modified (which would lead to all users replicating them as well) or the replication history of the local replica needs to be cleared.

The code in this entry is a sample to clear the replication history of the current database. It is sample code and hence does not contain error handling etc. and is provided as is - use at your own risk. The code is heavily based on an entry by Paul Ray in the Notes/Domino 4 and 5 Forum which contains the code to display the replication history of a database.

Sample Code

You can download the sample code here...

11/27/2008

XPages, here I come

Tags: Domino XPages development

I am sitting at Heathrow airport, waiting for my flight back to Frankfurt after attending a three-day workshop on XPages at the IBM Innovation Centre in Hursley. The workshop was great and my head is full of new stuff and ideas. Thanks to Tim, Matt and Chris for also making it a very enjoyable and entertaining event. If you want to know what we did in the workshop, Mick has covered it in more detail.

Now that I've spent some time working with XPages I am even more thrilled by the potential they possess. Web development on Domino has been possible for more than 12 years now, but it's never been easy to develop really sexy web applications on Domino. I'm not saying developing XPages applications is a piece of cake, but now you can create a really cool Domino web application without bending over backwards.

The potential of XPages, however, is not only that many things that took hacks or workarounds are now only one checkbox away, but they are also very powerful because you can customize and compute nearly eveything.

I am very much looking forward to applying this to one of our applications which we will then demo at our Lotusphere Comes To You event taking place on February 17 2009.

I am expecting XPages to really take off next year and I hope that many customers will see their potential. Along with DAOS, DCT and the ID vault, they are in my opinion one of the main drivers for Domino 8.5 deployment.

04/04/2008

What about Nuku'alofa?

QuickImage Tags: development

The ConvertToZone method of a NotesDateTime object changes the TimeZone and IsDST properties of a NotesDateTime object. The example code from the Designer help indicates that only values from -12 to 12 are valid. While testing I tried to use the time zone of Nuku'alofa (the capital of Tonga) which is GMT+13 (and which is available in time zone fields in Notes). Unfortunately the method throws error 4383 "invalid timezone number" on a value of 13 of the newzone parameter.

I hope my customer does not have an office in Tonga...

03/17/2008

Is it really that hard to tell if a document is encrypted? Please help!

Tags: development

I am a bit frustrated. For a customer application I need to determine whether a document a user has selected in a view is encrypted or not. "Geez, now, that's easy", I hear you say. That's what I thought as well. Exactly for that purpose the NotesGod invented the NotesDocument.IsEncrypted method (I thought). Unfortunately either I am missing something blatantly obvious or the property just doesn't work properly.

I have tested several situations in several client versions and it seems that in one situation the NotesDocument.IsEncrypted method is not working as expected (tested in Notes 6.5.6, 7.0.2 and 8.0.1).

Scenario

A user has opened the Inbox folder of his/her mail file. The user starts a LotusScript agent (in my case using an action) which processes all selected documents and tries to determine which of the selected documents are encrypted. This is done using the UnprocessedDocuments property of the current database.

Error Description

If a document is encrypted for the current user using his/her public key (which usually is the case for encrypted mails in a user's mailbox) the NotesDocument.IsEncrypted method returns False for all documents, regardless of whether they actually are encrypted or not.

When I looked at an encrypted document in the Debugger I saw to my amazement that not only the IsEncrypted property was false but also the items $Seal and $SealData were missing from the items list of the document. When looking at the document's properties in the Inbox (or any other view) the $Seal and $SealData items are listed in the properties box.

If the agent is executed on a document which is encrypted for another user (e.g. me running the agent in the mail file of a test user) the property works as expected. If the document is open in the UI the property works as expected as well.

I have tried @IsAvailable($Seal) and that works but only in a real formula language agent. If used in an Evaluate statement in my LotusScript agent it returns false as well.

Using the IsEncrypted method of the Body item does not help either because it also returns true if a document is signed but not encrypted.

I have searched the forums, the knowledge base and the fix list database without finding any trace of somebody else having a problem with this.

If anybody has an idea what's wrong here I'd appreciate any help very much.

02/12/2008

Composite Application Debug Tools

Tags: composite applications development

If you're into developing composite applications, there are tools you wouldn't want to miss. IBM has provided the Composite Application Debug Tools which are invaluable for every CA developer.

The tools are actually not new (they've been released in June 2007) but they haven't gotten much coverage yet so I hope to help make them known better.

Here's the description:

Property Broker Monitor: This tool is used for run time analysis of the property broker registry and events happening in the broker. The different tabs are dynamic and represent real-time events and data. They will all change as the environment changes around it. You can accomplish the following with the tool: Use the Console tab to see the different events happening in the broker.
The Current Page tab shows the components on the current page. It shows the actions and parameters for each of the components.
The Active Actions tab shows all active registered actions currently in the broker.
Active Wires tab shows all of the currently enabled wires in the broker.
Trace Properties with additional logging.
Topology Peek: This tool is used to see what the internal topology cache for the installed composite application looks like. It shows in a UI what is currently present in the cache. In general, if it is not in the Topology Peek it is not in the cached presentation of the application. This can assist in what the applications consists of on the client and should be refreshed when CA XML and definitions change on the fly.

Update

There's also the "Debugging and Troubleshooting Composite Applications" entry in the Composite Applications Wiki which provides some additional helpful information on debugging composite apps.

02/08/2008

@SetViewInfo([ResetViewFilter]) (I wish)

Tags: development

Today I was struggling again with @SetViewInfo. Although the idea behind this function is very nice, the implementation sucks (a little). Basically @SetViewInfo allows to restrict a view to display only documents from a single category. This is very nice to create a "my documents" view by making the first view column categorized and hidden displaying abbreviated user names. In the PostOpen event of the view insert a few lines of code:

REM {Set view filter for user's documents};
_user := @Name([Abbreviate]; @UserName);
@Command([ViewExpandAll]);
@SetViewInfo([SetViewFilter]; _user; "TheColumnName"; 1)
The disadvantage of @SetViewInfo is that the view filter remains active until the database is closed. So you will need to somehow reset the view filter when the user switches to another view. The easiest solution would be to put @SetViewInfo([ResetViewFilter]) or some such in the QueryClose event of the view. Unfortunately this parameter does not exist. A technote suggests to put @SetViewInfo([SetViewFilter]; temp ; 0 ;1) in the QueryClose event of the view (although undocumented and unsupported). Unfortunately this only throws a "Cannot execute the specified command" error ("This problem was resolved as: No Plans to Fix Ever").

I noticed that using

@Prompt([OK]; "You are about to close this view."; "Thank you for using this view. " + @NewLine +
"We hope you enjoyed your stay and are looking forward to seeing you again soon. " + @NewLine +
"Please press OK to actually close this view.");
@SetViewInfo([SetViewFilter]; temp ; 0 ;1)
did work. Quite understandably I didn't want to be tarred and feathered by the end users for this needless prompt, so I looked a bit further and finally came across a thread in the developerWorks Notes 6 and 7 Forum where Andre Guirard finally had the solution to put an end to my ordeal. Putting
@SetTargetFrame("NotesView");
@UpdateFormulaContext;
@Command([OpenView]; @Subset(@ViewTitle; -1));
@SetViewInfo([SetViewFilter]; ""; "TheColumnName"; 1)
in the QueryClose event resets the view filter successfully.

Thanks, Andre!

If you want to reset a view filter in the current view and want to go to the top of the current view there's a nice workaround Heinz-Ulrich Krause posted about a year ago.

02/08/2008

Complicated? Yes!

Tags: development WebDevelopment
Today I received an email from a customer with an attached database. A ready designed and tested version which should go to production at the beginning of march. Attached was also a short documentation.
Because I didn't know the developer I seriously looked at the document and the database. But while reading I felt there might be something wrong with this application. No description of how to set the ACL. No description of the included agents. No description of the configuration within the database. Nothing. But hey, what is the test environmet for? So I took the nsf, copied it to the server and had a look.
Launch options for browser opens a frameset. And the frameset opens a welcome page and a form. After starting from the browser, there was an agent printing the following to the server console three times a second:

HTTP Server: Agent 'AgentName' error: Object variable not set

I closed the browser and the message was gone. Next step: a look to the form in the Designer. The form contains some fields, some buttons and some html. And there were two JavaScripts: JS Header and onLoad. I found the agent causing the error in one of the Buttons started with a @Command. But I didn't see the button in the browser and so I didn't press it. The Notes Hide when's were empty but I've found somethingin the Button Extra HTML: ID: button, Style: display=none. But where the heck is the developer starting the agent? There must be something I've overseen. Then I looked into the onLoad JavaScript and gues what I've found:

document.all.button.click()

This is the first agent I've seen, which is started on the web by a hidden button clicked from a JavaScript.

I don't think this application will be used on our production server in march...

Shoot the developer!

08/31/2007

Images in Rich Text Items

Tags: development

As I described some hours ago I had a problem. I am sending e-mails from a Notes application which must contain a predefined footer which is stored in a rich text field of a setup document. In my code I use the AppendRTItem method of NotesRichTextItem to append the rich text item containing the footer to the body of the mail. All images in the footer did not display, instead I was prompted with "Note item not found" error messages.

I was nearly running out of ideas when I finally thought to check out the database properties. For some reason the option "Display images after loading" was turned on. I turned it off and tested again. Nope. I then edited the document storing the formatted footer and imported the same image again. Now it works. To my great amazement.

After some testing it turns out that you cannot programmatically copy images from rich text items which have been created while the "Display images after loading" database property is on. The same applies to lookups to these images. To display the contents of a rich text item from another document you can create a computed for display text field (or a rich text field) and retrieve the rich text field's content using a @DbLookup (see Technotes "@DbLookup and @DbColumn Questions and Answers" and "@DbLookup fails to return Rich Text field"). This also does not work if the property was turned on when the rich text item was saved.

08/31/2007

AppendRTItem

Tags: development

From the Domino Designer 7 Help document "Examples: AppendRTItem method" (emphasis mine):

Note The changes are not visible until the document (after the script has completed) is closed and reopened. Also note that the AppendRichTextItem method appends only the first 32K of a RichTextItem; the remainder is truncated.

"WTF?" I thought - how else could I easily put one rich text item into another? Fortunately my tests showed that this limitation actually seems not to exist (at least in Notes 6.5.6). Phew.

I have run into another problem, however. I am appending a richt text item containing a formatted footer message to another richt text item (the body of a mail the app is sending). Unfortunately this footer contains images. The footer item is appended to my mail body alright but when I open the mail I see a "Note item not found" message for every image and instead of the images only a gray border ist displayed.

I am still working to try and find a workaround since this should work (as Andre Guirard suggests in the developerworks forums (1) (2)).

I'll update this post when I've found a solution.

Update - Solved

See my next post for the solution.

08/29/2007

Reversing the order of a list in formula language

Tags: development

Some time ago I implemented a location search for one of our customers. The search results are company names and addresses. Today I was asked to also display the product groups for every company in the search results. When I showed this to the customer he said "That's great, but can you display the product groups in a specific order?". Of course, the company documents do not contain the product groups in that order. Since the product groups are set up in a profile document I thought it might be better to let the customer set the order in the profile document and use that list to determine the order of the elements in the list I'm displaying.

So, how do you order the elements of a list accordingly to another list? @Keywords is the answer.The help says "Given two text lists, returns only those items from the second list that are found in the first list.". Well it does that and it does it in the order of the elements in the second list.

_orderedlist := "elephant" : "zebra" : "crocodile" : "ostrich" : "lion";
_unorderedlist := "ostrich" : "zebra" : "lion";
_myorderedlist := @Keywords(_unorderedlist; _orderedlist);

So _myorderedlist now contains "zebra" : "ostrich" : "lion".

But, since I am displaying the product groups as an unordered list and the list is formatted so that all elements float right I needed to reverse the order of the list's elements. I remembered the rarely used [ToKeyword] keyword of the @Name function. It can be used to reverse the order of name components so that you can create views categorized by user's name components. The rest was easy:

_forward := "foo/" + @Implode(_myorderedlist; "/");
REM {_forward = "foo/zebra/ostrich/lion"};
_reverse := @Name([ToKeyword]; _forward);
REM {_reverse := "lion\zebra\ostrich"};
_reverselist := @Explode(_reverse; "\\");

I had to implode the list into a string separated by slashes to mimic a canonical name. Also, since [ToKeyword] strips the common name part, I had to prepend "foo" so that it could be thrown away. The list elements in the string are reversed and finally exploded.

I just love what you can do with a few lines of @formula code, especially when it comes to lists.

Disclaimer: No animals or lists were harmed in the making of this blog entry.

08/10/2007

NotesDateTime.NewTime Method?

Tags: development

The type-ahead help seems to know more than the rest of my Domino Designer. I haven't heard of a NewTime method of the NotesDateTime class and so has the help and the Designer itself.

Type-ahead help displays the NewTime method
Type-ahead help displays the NewTime method...
Type-ahead also knows the parameters of the method
... type-ahead even knows the parameters of the method...
But Domino Designer throws a compile error
... but Domino Designer throws a compile error. Makes me wonder...

07/25/2007

32KB Limit in a View Column for a Single Document?

Tags: development

We are currently developing an application with a web search form. The form comprises six fields the user can select values in to narrow down the result set (e.g. organization, department, location and so forth).

In addition to these six fields the user has a text field where he can enter a document title and then search for documents matching not only the document title search query but also the values from the other six aforementioned fields.

Also, the form should display an alphabet. In this alphabet all letters would be highlighted where at least one document exists where the document title would begin with that letter. Of course, this alphabetic list should also take into account the values from the six other fields.

The A-Z navigation looks something like this:
Screenshot of the A-Z Navigation

Since new documents will be added to the application only infrequently we wanted to use one big view to only make one @DbLookup for the whole list. The first (categorized) column of the view contains all permutations of all values from the six fields. The second column contains only the first letter of the document title.

So the column formula of the first column looks something like this: ((organization *+ department) *+ location) *+ ... and the second column like this: @Left(title; 1). To make sure it's all nice and clean you might want to @Trim the lists before and maybe use a separator, but I left that out for clarity's sake. The plan was to do a @DbLookup with the values of all six fields concatenated into one string (organization + department + location + ...) as the key. The result should be a list of all the letters matching this combination.

When the application was planned we only had four fields instead of six and everything was fine. When we had to add the two additional fields and when the number of values in each of the fields began to increase, we noticed that some of the letters were not turned into links despite the fact that the database did contain documents matching the combination of the six fields.

Since we know about the 32KB text fields limit we did the permutation in the view column assuming we are safe here but it seems that the value which is displayed for a single document in a view column also must not exceed 32KB even if the value is not contained in a document field. So it seems that the documents where the permutation of the six fields' values was > 32KB were dismissed from the view.

Has anybody else experienced this or can anybody confirm or confute my assumption?

06/06/2007

Design Element Replication Conflicts

Tags: development

As promised, here is the second thing I learned from the Taking Notes Podcast 43 "Interview with Ytria".

I always thought that when a design element in a Notes database is modified on two servers at the same time the one with the most recent time stamp "wins" when the database is replicated the next time. IBM says so in the Technote "What happens when changes are made to a design element in two replicas of a Notes database?".

In the interview Eric Houvenaghel stated that actually the design element with the higher sequence number will be the winner. I tested this on our development servers and it is actually true. The technote seems to be wrong.

Thus developers often hitting CTRL-S are less likely to lose the modifications they made if design replication conflicts should happen.

01/03/2007

Show-n-tell Thursday: Adding to multi-value fields in LotusScript

QuickImage Tags: development
I am subscribed to the SearchDomino tip newsletters - and sometimes I take the time reading them, as they sometimes have very valuable tips which helped several times to improve my @formula and LotusScript programming. Sometimes I am using an approach because I have used it over and over again, just because it works - without checking if there might a better approach. The tips can help to change that.

Sometimes the tips itself have a similar problem - they work, but there are better ways.

Today is Wednesday - but as DomBlog.de has been (too) quiet for the last few months I think it is time for a show-n-tell Thursday entry. It's about an improvement of the tip Adding to multi-value fields in LotusScript of Chuck Connell, and to make it easier for me, I'm just copying my comments I have emailed to SearchDomino into this entry.

----------------------------------------------

Hello,

regarding the current searchdomino developer tip:

It is somewhat inefficient to have multiple REDIM Preserve statements.

A better (and shorter) approach would be to REDIM the new array only once, beforehand, as we already know the number of values in the field.

So instead of
'Is the field time type? If Field.Type = DATETIMES Then 'Yes, it is time, get contents of field. OldTimeList = Field.Values 'Build an array of all existing values. i = 0 Forall s In OldTimeList Redim Preserve NewTimeList(i) NewTimeList(i) = s i = i+1 End Forall 'Add new value to end of array. Redim Preserve NewTimeList(i) NewTimeList (i) = NewTime 'Rewrite field with appended value Call ThisDoc.ReplaceItemValue(TIMES_FIELD, NewTimeList) 'Field is not time type, fix by setting it to this time Else ....
This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.

we would use
 
Dim intNewUBound as Integer
If Field.Type = DATETIMES Then
   'Yes, it is time, get contents of field. 
   OldTimeList = Field.Values
   'Build an array of all existing values.
   intNewUBound = ubound (OldTimeList) + 1
              'add one element to the new array - for the new value
   Redim NewTimeList(ubound (OldTimeList) + 1)
   For i = 0 to ubound (OldTimeList)
      newTimeList(i) = OldTimeList (i)
   Next 'Add new value to end of array.
   NewTimeList (intNewUBound) = NewTime
                      'Rewrite field with appended value
   Call ThisDoc.ReplaceItemValue(TIMES_FIELD, NewTimeList)
'Field is not time type, fix by setting it to this time
Else ....
 
An even better (shorter, quicker) approach would be using the ArrayAppend function
If Field.Type = DATETIMES Then
   Call ThisDoc.ReplaceItemValue (TIMES_FIELD, ArrayAppend (Field.Values, NewTime))
Else
   ...
 

Which is significantly shorter, and faster (which would matter if this function is called repeatedly).

12/14/2006

New Tool Versions

Tags: development

Chad Schelfhout has released a new version 1.3.0 of his Toolbar Functions. They are very handy for a lot of things many of us have written our own agents and actions for. Please make sure you check out his other great tools like Edit Document Fields or Open Audit.

Also, Ytria have released a new major version of their tools. The most noticeable thing is the new look which can be customized using themes. Go and check out these must-have tools. They are free in the read-only version and can be a huge time-saver.

05/11/2006

Recompile All LotusScript Error

Tags: development

When I try to recompile all LotusScript in any database in my Designer client I get an error "invalid or nonexistent document" after the first pass of building a dependecy tree has completed:

error: invalid or nonexistent document recompile all dialog after pass 1 while displaying error message

After clicking OK in the error dialog the recompile all dialog claims that although only pass one has completed that all code was compiled successfully.

recompile all dialog after pass 1 after displaying error message

Has anybody seen this before and what could be the reason for the error message? I have tried fixup, compact, removing orphaned agent notes in databases, I deleted my cache.ndk, compacted my desktop, all to no avail.

So it seems it has to do with my Designer installation (release 6.5.5). When I find the time I will try reinstalling. Quite annoying.

Update (19.05.2006)

I found a technote regarding this problem (SPR# MMAY6K9RFQ). It's a regression bug in 6.5.5. A hotfix is available on request and the issue will be fixed in 6.5.6.

Technorati tags:

02/15/2006

Worst Practices (5) - Redim. Please Redim. Could you please Redim.

Tags: development

Found today (coming from a different source than the other worst practices examples found so far):

Redim Preserve VAL01(0), VAL01(1), VAL01(2), VAL01(3), VAL01(4)

I would hope that just REDIMing once to a length of 5 would be sufficient - but you never know... . Also the preserve option is very "important", as this REDIM is used to set some initial values - there is nothing in this array beforehand (and it would be erased by the first redim anyway).

A fixed array of 5 elements (DIM VAL01(4)) would be even better. And using some *meaningful* variable name...


Here is the complete function (changed only to fit to the screen) - just to see some other tricks/hacks/nonsense like using the same array for displaying options and setting a new one:

Function GetDefaultValues01 '// Function to determine all default values needed for the e-mail convertion process ... Redim Preserve VAL01(0), VAL01(1), VAL01(2), VAL01(3), VAL01(4) '// Defining substitution display text ... VAL01(0) = "More Infos" VAL01(1) = "Contact to" VAL01(2) = {E-Mail address with an (AT) instead of the "@".} VAL01(3) = "Firstname, space, lastname of the user" VAL01(4) = WS.Prompt ( 6, _ "Please select what might be displayed instead of the current found e-mail address.",_ "Please select what you want to be displayed instead the currently found e-mail addresses ..."_ , VAL01(0), VAL01 ) If VAL01(4) = "" Then Messagebox "Cancel by user request.", 48, "Process canceled" End End If End Function

02/07/2006

Worst practices (4) - How to keep users waiting

Tags: development

Still blogging about the same old .... system we are currently migrating...


It is a web CMS used to feed several companies' websites and extranets. One of the major complaints regarding the old system was that it takes ages (up to a minute!) to show a list of downloads. What's suspicious is, that the time to display the download list seems to be independent from the number of downloads to be shown. I guessed that this was related to the heavy usage of readernames fields (which are necessary for the extranet functionality). When showing documents in a large view with a lot of read restrictions the server has to look into each of the documents before it can decide upon showing an entry or not. It is sometimes hard to avoid this (by using categorized views).


But I did not look for the cause of the bad performance (I have my reasons not to look into this code to often!).


The download database in question has several thousand documents and about 10 GB of size. That's not really big, but a decent size. We did some tweaking in our newly written app to speed it up. I still haven't tested it with the full size of documents (hope to do this today), but I was quite confident to speed it up at least a little bit.


Now I am sure it will!


Today I looked again into the code of the old app to make sure I'm migrating the correct fields. I looked into the view used to build the download list.

Keep the indexer busy!

The developer of the old application obviously noticed that the display of the download pages was very slow. It is done by a LotusScript agent, which builds a nice (?) looking DHTML tree (which has some other flaws, but that's another topic). So he started to use some caching tricks (storing the generated HTML in a separate document, which would be fetched if the current user had requested the same URL in the last hour or so). Which seems not to be working either, but I won't look into this any further.


The obvious and much more easier solution is of course to set the status of the document via a scheduled agent, depending on the data fields (there are other solutions, but that's the common approach).

02/07/2006

Self-documenting LotusScript code

Tags: development

Mikkel Heisterberg has published an article in the current issue of The View about his great tool for documenting LotusScript, LotusScript.doc. The article motivates programmers to actually document their code by showing that it does not have to be a cumbersome task which hence is often neglected, but it can be very easy to comment your code following a simple syntax and have LotusScript.doc create a detailed documentation automatically. Mikkel covers how to download and install LotusScript.doc and describes the first steps how to get started using it (which is actually not really hard to do).

We had a standard for code documentation before but it had the obvious downside that you actually had to look into the code to see the documentation. So we have moved to documenting all our code using LotusScript.doc (as I mentioned earlier) and thus can easily provide a code documentation which is accessible for everybody without having to look into loads of code. It makes the re-use of assets much easier and will facilitate the ripening of these assets as more and more people use and improve it.

I can only recommend looking into LotusScript.doc to every Notes Domino developer. If you are a subscriber to The View, read the article, otherwise just download the tool and take a look at the documentation over at lsdoc.org.

In the next issue of The View Mikkel will write more about LotusScript.doc and how it was built.

02/07/2006

Worst Practices (3)

Tags: development
Another example (remember: this is the productive code!):

Aaaarrrgghhhhh

Maybe the developer of the application met the same fate as Joseph of Arimathea...

02/06/2006

Worst Practices... (continued)

Tags: development

Another gem I stumbled upon today:

A "hidden" field:
Where is that field name????

hidden using the text color:
a hidden field!

well ... sort of hidden

Probably also a cool logo: grey eagle on grey background....

Might have been better to have at least *some* basic education in Lotus Notes application development.

02/03/2006

Worst Practices....

Tags: development

Currently I have to migrate documents from a (very complex) Notes/Domino application (written by someone else, no, not at our company!) to a Notes/Domino application written by us. By the way: the same bl**dy application as
blogged some time ago.

After migrating some documents I tested them. I noticed, that my input validation (done by QuerySave, calling some script library functions as we have to do some complex computation) was broken: I was able to enter wrong data, got a (correct) error message - but when I cancelled out the trash had been saved.


So I started debugging the input validation, the script library, and so on. But I could not explain what was going on - I searched for a NotesDocument.save in the LS code, then for @Command([FileSave]) in some of the buttions. But of course I could not find anything (who would do such things?).


Finally I found out.


They had saved *some* (not all) of their documents with an item "SaveOptions", which was set to 1. And of course that was neither visible in the forms nor commented anywhere. Which leads to saving the documents when cancelling without even being asked.

01/26/2006

Object Orientated LotusScript Techniques and Tips (BP312)

Tags: development

Unfortunately I was a bit late for his session and got overflowed so I could not see if Wild Bill Buchan was wearing his Kilt. But even in overflow his presentation is well worth going to. He is one of the most entertaining presenters at Lotusphere and the stuff he tells in this session is perfectly suited to get you started with OO programming in LotusScript.

Technorati tag:

01/25/2006

Directory Assistance is Over-Protective

Tags: development

I have developed user management application for a customer which is also included in the server's directory assistance. The database uses some views I copied from the Domino Directory to enable it properly to be used in directory assistance. To keep things simple my person form is called "Person" and the field names are the same as in the DD's person form (e.g. FirstName, LastName, Type, ...).

The user management application also includes company documents and each company has one special user who is allowed to create and edit additional users for that company. Thus this user has author access in the database ACL with the right to create documents. Now whenever this special user edits a person document from either a web browser or the Notes client all the fields for which in the Domino Directory's Person form the security setting "must have at least Editor access to use" is set some random fields are treated as if this flag is set in my form as well (which of course isn't the case). They all get the "PROTECTED" flag set. This prevents the fields from being modified by an author user and thus prevents my special user from modifying the person documents. Bummer. I don't know yet how to solve this since the logical solution would be to rename the fields. But this again will probably prevent my application from working as a directory in directory assistance. Another way would be to copy the documents to a "real" Domino Directory but I hope I can avoid that overhead.

The good thing is - I am at Lotusphere where all the Domino developers are hanging around in the labs. I am going to go there later and hopefully I will get a good solution to my dilemma. Let's hope for the best.

First Update (26.01.2006)

I talked to Steve Leland about the problem and showed it to him. Him promised to look into this but of course could not fix it now. Since the application needs to be delivered in the very near future I will have to use a workaround. I will probably rename the fields and use a backend agent running with the server's rights to copy the edit fields to the actual fields after the WebQuerySave agent has run.

Second Update (06.02.2006)

I have tried several workarounds including a WebQuerySave agent not running as a web user which starts another agent (using the RunOnServer method) running on behalf of the server which removes the "protected" flags. I also tried to rename the (as I though then) critical fields like FirstName, LastName etc. but since it can affect any field on the form (no matter if they are editable or computed or computed when composed) I have run out of options. My only resolve now is to remove the database from directory assistance and write an agent to synchronize the person documents with a "real" domino directory.

I have searched the knowledge base and LDD but apparently nobody else ever encountered the problem (which is reproducable with any database which is included in directory assistance btw.).

Third Update (06.02.2006)

The problem now has been assigned an SPR number (SLED6LRN9K). I'll update this entry when I get any news on it.

01/25/2006

The Ultimate Make-Over of an IBM Lotus Domino Site (HND209)

Tags: development

Henry Newberry and Scott Good hosted the hands-on session. The databases were available on USB sticks so everybody could use their own laptop or one of the classrom machines. The session was pretty packed but not completely full. They had hand-outs for the session, it all was quite well-prepared (quite a difference to the hands-on I attended yesterday).

The session gives Notes developers a good start to developing web applications. They used the standard release 6.5 discussion database template and modified it so that it looks much nicer, got rid of the frames, the Java applets etc. Pretty much everything worked quite well, although the speed of the presentation was really fast so that developers without a solid experience may have had problems following. Scott explained the different CSS settings pretty well so that users with only a basic understanding of web development will surely take a lot away from the session.

A few comments on the session content: You wouldn't want to use the unit "pt" for font-size. This will break the page design on Macintosh computers. Also, for accessibility reasons font sizes should use relative units like "em", "ex" or "%". The same applies to the width and height of the divs and the absoulte positioning of elements should also be handeled with care. If a user wants to increase the font size in the browser the container blocks should resize (and move) also for the content to be still readable.

Developers wanting to go deeper into facelifting Domino web applications should also look into the stuff which was presented in session BP308.

Technorati tag:

01/25/2006

Application Performance Techniques for IBM Lotus Domino Developers (BP302)

Tags: development

Just as last year this is a must-see for every Notes Domino Developer. Jamie Magee and Kevin Marshall presented a great session full of real-life coding tips and pitfalls of Notes and Domino development. They updated last year's presentation to include release 7 and so proved a list of things to watch out for if an application performs poorly (or - even better - to avoid this beforehand).

I would like to add two things to their presentation, though. Instead of using the @DbLookup function to retrieve data from another document it is faster to get the value of the field directly using @GetDocField if you know the UNID of the source document. (See Mika Heinonen's blog on LotusScript Speed Testing as of 15 August 2005 about this and other speed testing issues.)

Also, it is faster if you use "NotesDocument.GetItemValue" and "NotesDocument.ReplaceItemValue" instead of the shortcut "NotesDocument.ItemName".

Our fellow developers at home will surely have the pleasure of being subjected to the slides - it may then not be as entertaining as if Jamie and Kevin did it (and I can't throw a t-shirt the way Kevin does) but it will hopefully be as instructive and useful as it was for me.

Technorati tags:

01/24/2006

IBM Lotus Domino 7.x (and 6.x) Application Performance Optimization (AD206)

Tags: development

This session about Domino application performance complements very well the second session on this subject which takes part right afterwards. Frederic Dahm and Luc Groleau to the more general approach to that topic and presented a lot of things a Domino developer (or any developer) should consider before and while developing application. The slides are very well taking a look at and showing to all fellow developers.

In the second part of the session they talked a little about tools to use in performance optimization. Of course DDM and agent profiling are great tools which were introduced in Notes Domino 7 and every developer should use them. They also mentioned the page detailer tool which is available from IBM alphaworks. It can be a great help to analyze the performance of web applications.

Technorati tags:

01/24/2006

Building IBM Lotus Domino Applications with Ajax Plugins (HND201)

Tags: development

I had hoped to get a little more insight (and also my hands on) the Domino Facelift code in that hands-on-session. My expectations were high after a really good session yesterday. Unfortunately Lance and Dwight were fighting with the infrastructure as were the participants. I must admit that I left 15 minutes early but until then I had not seen much more than in the presentation the day before. I did get the chance to look into the code a little (and there's lot of it). It looked well-written but does not include many comments. I am still looking very much forward to trying the DFL database out, since the idea is great and for alpha code (as Dwight indicated repeatedly) it works pretty well. I am sure the two guys will prepare the infrastructure better for the repeat session on Thursday. I would recommend though to pre-install the needed databases, the Firefox browser and the extensions needed (Venkman JavaScript debugger, Developer Tools, and the Fiddler HTTP debugging proxy and only to demo the installation process to the users. Too much can happen when 30 people simultaneously start downloading and installing stuff. As we have seen the trouble which can arise doing that can cost precious time.

Technorati tags:

01/23/2006

Tips and Topics for Developing Web Services in IBM Lotus Domino Designer (AD203)

Tags: development

Tom Carriker and Steve Nikopoulos gave a great introduction for the experienced Domino developer to get started with Web Services. Another basic introduction (which does not go into the same depth) is contained in the Lotus Domino 7 Application Development Redpaper in chapter 3. The presentation contains lots of code snippets and I definitely recommend to get it.

Technorati tags:

01/23/2006

Ajax and IBM Lotus Domino - The Cleanest, Slickest Sites in Town (AD216)

Tags: development

The Turtle gave a good, entertaining and well-received overview of how to get started in using Ajax and what it actually is. He showed examples and had some demo code to show the principles which he will hopefully make available.

Technorati tags:

01/23/2006

IBM Lotus Domino Web Facelift Using AJAX and DXL (BP308)

Tags: development

This was actually my first real session after the general opening session. I spent the previous slot in the certification prep lab looking into exam 701 (Notes 7 AppDev update). The selftest software test was quite good, the CertFX one seemed to contain some errors.

Lance Spellman and Dwight Wilbanks delivered a session that was inspiring, fun and instructive. They presented Domino Facelift (DFL) which might become a framework for a better web-enablement of Domino web applications. The approach they use is clever and can easily implemented into nearly any existing Domino web application. They have a database which contains all the code necessary. To use it for example in a form you just need to include references to the CSS file and the JavaScript code in the facelift database. The database reads the form's DXL and processes it. It then returns a facelifted form with a lot of JavaScript calls and CSS references. This will make the web form behave a lot more like a Notes form by just using the settings you made in the Notes form. Date fields only accept valid date values, number fields only accept valid numbers etc.. You can also use enable your form's rich text fields to use FCKeditor just by setting a CSS class in the field properties.

A little different approach is used for views. From the facelift database you select the view in your target database which you want to facelift. The facelift database then adds a $$ViewTemplate form for the specified view which calls the facelift JavaScript and CSS code. Some features of the view facelift is the support of (cascaded) simple actions which are automatically translated (and even do work on multiple selected documents in the view), a quick search to jump to a specific view entry (just like in Notes) and a scrollable view.

DFL definitely has a big potential and I think it is a great tool to use (and of course to expand, share and thus improve). Get the DFL database at www.faceliftfordomino.com and also get the presentation if you are an attendee of Lotusphere and are interested in Ajax.

Technorati tags:

01/22/2006

The Hitchhiker's Guide to Microsoft Office Integration with IBM Lotus Notes and Domino (JMP 204)

Tags: development

Every Notes Domino Developer sooner or later gets to the point where the users wish to do something Notes Domino can't do. Like printing. Or charts. John D. Head has for many years now delivered great presentations on how to integrate Notes and MS Office to do exactly that. As in the previous years there's a lot of deep dive into the dephts of COM, OLE and their friends. Loads of code to take away (see John's website) will help every developer to easily do mail merge or to populate Word documents with information from Notes documents or to access Notes data from inside Word. It also includes code to to cool stuff with Excel. He and Alex Kassabov presented an entertaining and really valuable session which is worth going every year since the information is updated to accommodate the changing object models of Word, Excel etc. and the sample code also is updated and enhanced. Actually it's not the same session every year but the main subject has been so far. Even if you have done MS Office integration before you will take away new ideas (and did I mention it - code).

Another great point they made was to use web services to integrate Notes data into MS Office documents. That approach can also be used when the user works from a browser.

If you want to know more about that subject I recomment their second session Extreme Integration - Techniques for Advanced Integration of Office and OpenOffice with IBM Lotus Notes and Domino on Tuesday.

One tip I found helpful is the object catalog in the Visual Basic editor. I have seen many developers trying to find out the value of system constants (like wdAlignParagraphLeft for example). There's a very helpful database by Tom Duff containing all these constants (which will also be available at John's website as well but you can also open the Visual Basic editor and just press F2 which will open the object catalog. You can there just enter the constant name and search for it and get its value.

Technorati tags:

12/21/2005

No more info... sequel!

Tags: development
More on helpful error messages in Domino Designer:

This time I got a "no more info! Would you like to see more information?" error:
No more info! Would you like more info?

Huh?

Well, I would, but I only get the agent log if clicking on Ja (yes)...
THIS is more info!

12/20/2005

Another one for the UI hall of shame

Tags: development
Names field properties

Don't get me wrong - Domino Designer is a great tool. But some of the UI details are just not very good. If have always avoided using the option "use view dialog for choices" in names fields. Today I was reminded again why.

Not only is the selector far too small to be usable. It also displays a wrong view name if you have selected a view with a backslash in the name. Tsk.

12/15/2005

Domino Messed Up My Documents

Tags: development

We are working on a rather complex Domino based web application currently. When I was testing the application with a user with Author access to the database I noticed that after editing and saving documents in a browser some fields kept their original values even though they are editable and I changed them. Intense testing showed that the fields affected by this phenomenon did change randomly from session to session. Looking at the documents with the excellent NoteMan tool by MartinScott I noticed that some fields had the "protected" flag set. This flag is set in fields if the field in the form has the security option "Must have at least Editor access to use" set. None of the fields on the forms in that application have this setting. At first I thought that maybe the WebQuerySave agent was doing stuff wrong but the fields in a document which had been edited kept the new values all through the WQS agent. Only if I saved the document in the WQS agent (for testing purposes) the old value came back during the agent run. If I didn't call doc.save in the WQS agent the old values came back after the WQS finished.

I built a new form from scratch which only had several text fields, an Author field and a submit button, no WQS agent. Using that form I created and modified documents. They showed the same symptoms. The database properties, the ACL and everything else were standard.

Obviously something was wrong with the database. New copies and replicas had the same problem. I finally created a new database from scratch and copied all design elements manually to that database. The problems have vanished but now I need to go through all subforms, forms and views and fix all shared actions since they were completely mixed up even though I copied them as well. Grrrr...

Update

Well, I thought I had it solved, but Domino taught me better. After creating a new database on our Release 6 dev server I didn't see "protected" flags in the documents. I was happy. But not for long. A few document edits later I had protected flags again.

On our Release 7 server about 40% of the fields hat protected flags after being edited in the web by a user with author access. Currently I have no idea how to solve this. There has to be something in the database causing this but I fear it will take me a long time to figure that out. Other databases seem to be ok. Maybe I should take the application to the lab at Lotusphere - if only for a good laugh (at me) by the developers

Update from Lotusphere

Some further inverstigation and an inspiring environment sometimes helps.

12/02/2005

No more info....

Tags: development
Generic LSE Failure (no more info!) - no more info???? No info at all !!Got this helpful message box when trying to open a document in my Lotus Notes client.

Solution: I had to open one of the subforms in the form used to display the document in Domino Designer. Entered a blank and saved it. Everything works fine again (till next time).

Seems to be a variant of the "Error processing use list module" error (which is also not saying whats wrong - but at least shows the subform having the problem:
Meaning: enter a blank in the subform mentioned and save it...
Domino Designer seems to be confused about all the LotusScript Libraries in use. But there is no need to confuse me by using confusing error messages...

11/09/2005

LotusScript.doc

Tags: development

We have been playing around with LotusScript.doc, a tool by Mikkel Heisterberg to create a documentation of LotusScript code in a Notes database. Overall it looks quite good, even without modifiying the code of the database the tool created a nice Javadoc-Style documentation of the LotusScript code.

The documentation syntax is very similar to Javadoc. LotusScript.doc currently supports seven @-parameters and can be used in most design elements.

If our further tests are successful we will probably switch our documentation style to that syntax. If you are not using a standardised documentation format for your LotusScript code (esp. for the header) yet this is a good start anyway.

Even though it crashes on one of our more complex databases (see below) and does not yet work 100% it seems quite promising. An enhancement I would like to see is the option to extend/configure it, e.g. to add new @-parameters.

LotusScript.doc will be available in two editions, the free community edition (the one we are testing) and a commercial edition which is yet to be released.

JSDoc

We have also begun to use JSDoc to document our JavaScript code. It is not that well suited for Domino based web development since it is a Perl tool which can only be applied to .js files but is is still very handy to create a nice documentation of JavaScript Libraries for example.

Update (26.01.2006)

As mentioned above, LotusScript.doc crashes on one of our applications. To find the reason, I met up with Mikkel at Lotusphere and we took a deeper look into it. We tried to export the whole database design to DXL using a simple agent and saw the Notes client crash with a red box of death. I went to the developer's lab and spoke to Dick Annicchiarico. Looking at the NSD file he remembered a bug in the DXLExporter (SPR #DANO67JPRX) which is fixed in release 7.0 and will be fixed in release 6.5.6. Since our development server needs to be release 6 for the time being (most of our clients have not migrated their environment yet) we will have to wait a little longer but nevertheless will keep on documenting.

10/21/2005

Fun with @DBLookup

Tags: development

I thought as a long term (experienced?) Lotus Notes developer I knew everything about a basic function of Notes: @DBLookup

 

I admit: When I first had contact with this beast (in Lotus Notes 3.1, I think), I had some problems with the function. Mostly this was because of my missing knowledge about functions like @IsError, and my IT background (I learned "real" programming languages and "real" databases before starting to work with Notes). But finally I managed to work with it - and was a happy user of @DBLookup. Until today, when I lost some hours, and finally learned something new about it.

 

The setup: In the context of a complex web application I have to lookup some documents and display information about them within a web page. The keys for the documents to lookup are stored in a (multi-value) field in the document which is shown as web page. So I'm just passing the field as key into the @DBLookup, like this

 

 @If (MarginalNoteKeys = ""; @Return (""); "");
_view := "vwCustomLookupMarginalNotes";
_column := 2;
_MarginalNoteList := @DbLookup ("Notes" : "NoCache"; ""; _view; MarginalNoteKeys ; _column);
@If (@IsError (_MarginalNoteList); @Return (""); "");
...

Everything worked fine. Until I started to test this functionality in the more complex part of the web app: Some of the documents will be copied over to another database. So it might be that only some of the documents to be looked up (the "marginal notes") are available there - so the key list will contain some values/keys where we won't find a document for.

 

My first test showed the error message "entry not found in index". But there were some documents which should have been found. Hmm.

Some more tests: sometimes some of the marginal notes were displayed - but not all that I expected.

 

After a lot of testing I found out, that my guess how @DBLookup worked was wrong. I thought, that it would return all the documents found for the keys which "worked", and ignore the keys which were not found.

 

Wrong.

 

@DBLookup will get all hits until the first key which is not found and will stop processing instantly.

I checked my Notes 5 client: same behaviour.

Solution (available with Notes 6):

Add the keyword [FailSilent] to the function call. Then @DBLookup will process all keys and will return just empty list elements for the keys which are not found in the view.

 

_MarginalNoteList := @DbLookup ("Notes" : "NoCache"; ""; _view; MarginalNoteKeys ; _column; [FailSilent]);

 

You still need the error handling (@IsError) to handle typos in the view name etc.

07/27/2005

Using Notes:// URL to open a form ...

Tags: development

Reading Duffbert's "Using Notes:// URL to open a form for data entry..." got me curious about what you can do using Notes:// links. I thought that since they work a bit like Domino URLs I might try some combinations. I took a Notes: link of a document and replaced the UNID of the document with the UNID of the log entry form in an agent log database. I took the UNID from the design element properties box for simplicity (a simple agent is much more convenient though). Clicking the link did not what I had hoped (open the form for data input in my Notes client) but instead showed me this:

Form Design in Notes Client

07/01/2005

What Are Your Parent's Views?

Tags: development

Well, to be honest - I don't know. But apart from knowing what the elders think it might sometimes be as valuable to know a document's parent view...

If you ever have received a mail with a doclink - either from a workflow application or from a colleague who sent you a link message to the latest joke in the department's fun database - you might have wanted to go up to the view the linked document is contained in to see the context of the document (or to look at more jokes).

Mail with doclink

Inspired by Alan Lepofsky's IBM Lotus Notes/Domino Hints and Tips I wanted to share a little known tip how to do exactly that. Notes provides a lot of useful features which are sometimes not obvious to the user. If you have opened the linked document you can open the document's parent view by selecting "View - Go up to Parent View" from the menu. This will take you to the (default) view of the database and position the cursor on the document you were in.

Menu: View - Go up to Parent View

Many more great tips (some of them are even available in German) are available in Alan's Blog.

05/07/2005

Programmatically In-Line Editing Attachments

Tags: development

I recently wrote a small workflow application for one of our clients. The Notes app provides the workflow capabilities while the actual form is an Excel sheet which ist attached to a Notes Document.

Since some of the users kept hitting "open" instead of "edit" from the attachment's context menu, infobox, or menu (and were complaining that their changes got lost) my client asked me to help avoid this problem.

Unfortunately there is no programmatic way to start in-line-editing the attachment. The solution I found uses a simple API call as suggested in "How to Simulate User Keyboard Events in LotusScript Without Using SendKeys (user32.dll)" in the Lotus Software Knowledge Base. The function "keybd_event" in the Windows library "user32.dll" simulates keyboard events at the operating system level. So I only had to write some code in a button to put the cursor in the rich text field containing the attachment, select the attachment and select the menu entry "Attachment - Edit" using the correct key sequence (which happens to be ALT-T-E in English clients and ALT-H-ENTER-B in German clients).

04/27/2005

Rewriting other developer's software

Tags: development

We have just started a project, where we are relaunching several websites for a customer. These websites are built by another IT consultancy (who have become insolvent) using their own web CMS, based on Lotus Domino.

It is always difficult to deal with software written by someone else. In this case we decided (very quickly) to redo everything without looking (much) into the old solution, as we are using our own, existing CMS framework, which has got a completely different structure.

This seems to be a good idea: I just browsed through the design of the old CMS (as I have to migrate the existing contents later on), and found a lot of things I definitely don't want to look at longer than necessary:

  • This is a list of agents, all of them visible to the user in the action menu:
  • Change RepID??? - whoa!
  • An example for an agent:
  • Option Declare is used nearly nowhere in the script code.
  • Alias names are used only "sometimes".
  • Script Libraries are used rarely, and there are some very "special" ones:

    (this is the complete ! script library.)

... to be continued ...

03/11/2005

Not A Form

Tags: development
A picture named M2

03/11/2005

Signing Code in E-Mails - The Sequel

Tags: development

I thought I had finally managed to get my button signed - until I tested in ND 6. It seems that encrypting the mail wasn't enough here. I spent some more time researching ways of getting rid of those nerving ECL warnings claiming that that the button a LotusScript agent was sending out in mails had "No Signature" even though the mail itself was properly signed.

I finally returned to a response posted by Rod Whiteley in a thread in the ND 6 forum at LDD which described the same problem I had. He mentioned an undocumented C API function called NSFMemorySign that might help and that he wrote some LotusScript code to sign a LotusScript button. He offered to send it so I contacted him.

Even though he is currently not working with Notes he replied and sent me the code. What I got was far more than I expected. It was a whole database containing a tutorial, demo code, script libraries with several classes to handle Rich Text items thruoght the C API. I haven't used the C API much before but it took me no time to take Rod's code and include it in my application. What can I say - it just worked. I didn't even need to sign or encrypt the mail itself anymore.

Thanks Rod, you saved my day .

So, what did I do? I first tried to sign the Rich Text item in the profile document that contains the button and which is copied to the e-mails sent by my agent. For some reason I first didn't get this to work even though Notes said the code was signed. My second approach to get it working any way was to sign the body of the mails sent by the agent. That worked but it obviously only works on Windows servers (which ist bad because my customer's servers are running on AIX).

So I went back to my profile document and looked at it more closely. I discovered that even though the code was signed by Rod's script the IsSigned property of the Rich Text item was not set. I set it to true and that did the trick. I am a happy developer again.

02/18/2005

Signing Code in E-Mails

Tags: development

Today I have been working on a (Notes 6.5) application that is used to handle SPAM mails. All SPAM is sent to a mail-in database. In this database the users can create setup documents where they can specify if they want to have these SPAM mails forwarded to them anyway. To enable the users to find false positives in the SPAM detection process every day a scheduled agent sends a newsletter to all users who are not having their SPAM mails forwarded to them. The newsletter contains a list of all SPAM mails they have received the previous day. It also includes a button (not a stored form) which enables them to have all their SPAM mails of the previous day forwarded to them.

The interesting part was that the users were getting ECL alerts every time they clicked the button since the code in the button did not have a signature. Since I didn't want to change the administration ECL to allow "No Signature" to do stuff on the clients I had to find a way to avoid the ECL alerts. I don't think that users would find a button in a mail called "SPAM Newsletter" very trustworthy if the button would create security warnings.

So I have played around with different approaches to sign the code in the mail. I tried signing the mail itself, I tried signing the code where the button came from, but all to no avail. Notes told the mail was signed alright but the ECL alerts kept popping up.

Finally I tried not only to sign the mail but also to encrypt it (using the properties SignOnSend and EncryptOnSend). That did the trick (at least in R5).

Notes is probably working as designed ... but not as I would have expected it. That proves again that even after developing Notes and Domino applications for many years it still can surprise you every day. That is one of the things I like about Notes - it's very powerful and sometimes very challenging.

Search

Calendar

MiscLinks

We Use Ytria Lotus Notes Tools For Faster Notes Development and Better Domino Administration

Tags

Site Info