Lotus Notes Domino

You can access Lotus notes documents from outside Lotus Notes either using an Internet url (if your Lotus Notes database is web enabled) or you can access and open up a specific Lotus Notes document in the Lotus Notes client from for example Excel or Word in other ways.

Duffbert has some good information on this. One of the tips is to get the document’s Notes url and paste it in as a hyperlink in Excel. To accomplish that you need to find the document’s UNID. Or you can use the Sametime client for some translation.

Create a document link for the Lotus Notes document to which you want to create a link to. Paste this into a Sametime chat window. As you can see the document link is translated into a Notes URL. Now, simply paste it in as the hyperlink address in excel and you have a funtional Notes link.

When you paste the document link into a Sametime chat window it will be translated into a Notes URL, looking something like this, which can be accessed from outside Lotus Notes. Be aware of access though, these rules still apply.

notes://DOMINOSERVER/C1257465003C1F7D/BF25AB0F47BA5DD785256

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

14 comments

If you for instance have Lotus Notes version 7 and would like to install version 8 on the side, i.e. you want to keep both installations on one computer. Then you have a good description of doing so here. According to the instructions you have to make copies and rename at some places. But you can also do it another way that takes a little bit longer time but really don’t require more than one change on one installation window.

So let’s say you have version 7 and you want to install version 8.5. Start the executable for Lotus Notes 8.5. Go through the installation process. When you come to the point where the wizard asks for the location of where to install the program – change the path from <path>/notes and <path>/notes/data to <path>/notes8 and <path>/notes8/data or if there are other similar change them.

Now Lotus Notes 8 will be installed in a new directory. However your 7 version will not work. If you install the 7 version again now though without making any changes you will have two versions that should be fully functional. I don’t think you should run them concurrently though,

The 7 version kept the Teamstudio toolbar buttons, workspace and so on. But you will have to adjust this for the new 8.5 version howver.

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

5 comments

A web service consumer example

by Niklas Waller on December 16, 2008

in Lotus Notes Domino

I have just for educational purposes created a simple web service consumer with Lotus Domino Designer 8.5 Beta 2. So I thought I’d share and perhaps make someone happy.

For this example I found a web service on webservicex.net which was kind of funny. It is called BibleWebservice and let’s you get biblic information by book, chapter and verse. The address to the WSDL-file can be found here.

1. Create a web service consumer element. Name it and point to the WSDL-file either local or the url. The web service consumer gets created for you. Copy the class name that gets created, i.e. ‘BibleWebserviceSoap_n0′.

%INCLUDE “lsxsd.lss”
Const n0 = “http://www.webserviceX.NET”
Class BibleWebserviceSoap_n0 As PortTypeBase

Sub NEW
Call Service.Initialize (“HttpWwwWebserviceXNETBibleWebservice”, _
“BibleWebservice.BibleWebserviceSoap”, “http://www.webservicex.net/BibleWebservice.asmx”, _
“BibleWebserviceSoap_n0″)

End Sub

Function GetBibleWordsByChapterAndVerse(BookTitle As XSD_STRING, chapter As Long, _
Verse As Long) As XSD_STRING
Set GetBibleWordsByChapterAndVerse = Service.Invoke(“GetBibleWordsByChapterAndVerse”, BookTitle, chapter, Verse)
End Function

Function GetBibleWordsbyKeyWord(BibleWords As XSD_STRING) As XSD_STRING
Set GetBibleWordsbyKeyWord = Service.Invoke(“GetBibleWordsbyKeyWord”, BibleWords)
End Function

Function GetBookTitles() As XSD_STRING
Set GetBookTitles = Service.Invoke(“GetBookTitles”)
End Function

Function GetBibleWordsByBookTitleAndChapter(BookTitle As XSD_STRING, chapter As Long) As XSD_STRING
Set GetBibleWordsByBookTitleAndChapter = Service.Invoke(“GetBibleWordsByBookTitleAndChapter”, BookTitle, chapter)
End Function

End Class

2. Create an agent. Add “Use ‘web service consumer name’ ” in ‘Options’.
3. Set target as ‘None’ in the agent properties,
4. Add this code in the ‘initialize’ section

Dim bible As New BibleWebserviceSoap_n0
Dim bookTitles As XSD_STRING
Dim session As New NotesSession
Dim inputStream As NotesStream
Dim domParser As NotesDOMParser
Dim domDoc As NotesDOMDocumentNode
Dim domNodeList As NotesDOMNodeList
Dim domNode As NotesDOMNode

Set inputStream = session.CreateStream

Set bookTitles = bible.GetBookTitles()
Call inputStream.WriteText(bookTitles.getValueAsString())

Set domParser = session.CreateDOMParser(inputStream)
Call domParser.Process
Set domDoc = domParser.Document

Set domNodeList = domDoc.GetElementsByTagName(“BookTitle”)
Set domNode = domNodeList.GetItem(1)

‘ Now get the text in the tag and prompt it to the user (or something else)
msgbox domNode.FirstChild.NodeValue

5. Run the agent

So this agent will, when run, display the name of the first book in a message box to you which is ‘Genesis’.

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

33 comments

The other day I needed to calculate how much space, i.e. size in Bytes, that all attachments took up in X specific Lotus Notes databases.

So I googled some and found a very good solution already made by Stefan H Wissel.
Using this you will get a good coverage on how many attachments there are per database and how much space it corresponds to in Bytes.

Since this takes some time to run you can easily modify the script to loop through only a subset of predefined databases instead if you are only interested in a few and not all.

I modified the initialize sub in agent ”ScanForSize” this way:

Sub Initialize
Dim s As New NotesSession
Dim db As NotesDatabase
Dim curDB As NotesDatabase
Dim serverName As String
Dim DbArr(7) As String
Dim db1, db2, db3, db4, db5, db6, db7, db8 As String

Set db = s.CurrentDatabase

‘ Server
serverName = “Server1/Acme”

‘ Database file paths
db1 = “Path\Filename1.nsf”
db2 = “Path\Filename2.nsf”
db3 = “Path\Filename3.nsf”
db4 = “Path\Filename4.nsf”
db5 = “Path\Filename5.nsf”
db6 = “Path\Filename6.nsf”
db7 = “Path\Filename7.nsf”
db8 = “Path\Filename8.nsf”

‘ File array with the database file paths
DbArr(0) = db1
DbArr(1) = db2
DbArr(2) = db3
DbArr(3) = db4
DbArr(4) = db5
DbArr(5) = db6
DbArr(6) = db7
DbArr(7) = db8

Forall dbItem In DbArr
Set curDB = s.GetDatabase(serverName, dbItem)
Print “Working on ” & curDB.FilePath
Call countThis(curDB, db)
End Forall

Msgbox “Run completed”
End Sub

Another suggestion is to modify the ‘countThis’ sub to show statistics for everything regardsless if the database has attachments or not. I.e. comment the if-statement.

‘If curSize.AttachmentCount > 0 Then
Call curSize.save(reportDB)
‘End If

A thing to be aware of is the error message “Execution time limit exceeded by Agent”, which means that the execution time of agents, i.e. how long agents are allowed to run has been exceeded. So you have to adjust this parameter for a long agent run or else it will suddenly stop run.

A tip is to schedule the agent to run on the server instead of pressing the button. Your client will not hang so you can continue to work and it will also process faster.

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

Be the first to comment

I needed to create a simple Lotus Notes Web Service. Since this is version 7 we are talking about it is a provider. The consumer comes in version 8 although there are very good ways to mimic the behaviour.

These tutorials on creating web services in Lotus Notes by Julian Robichaux are great:
- Practical Web services in IBM Lotus Domino 7: What are Web services and why are they important?
- Practical Web services in IBM Lotus Domino 7: Writing and testing simple Web services
- Practical Web services in IBM Lotus Domino 7: Writing complex Web services

As I wrote there are good ways of creating a web service consumer even in version 7. See this article by Joachim Dagerot for more on this. If you have version 8 it is even more simple.

Anyway, to the core of this blog entry. I created a simple web service by first writing a lotusscript class with a couple of simple methods in it. I set the adjustments on the web service to ‘RPC’ as programming model and ‘Doc/literal’ as SOAP message format, since ‘Doc/literal’ was what the consumer wanted for some reason:

Class test2
Private session As NotesSession
Private db As NotesDatabase

Public Sub New ()
Set session = New NotesSession
Set db = session.CurrentDatabase
End Sub

Public Function PutAndGetModString (txt As String) As String
PutAndGetString = txt + “_mod”
End Function

Public Function GetDbName () As String
GetDbName = db.Title
End Function

Public Function GetTest () As String
Bla = “Response string”
End Function

End Class

I exported the WSDL-file by pressing the button ‘Export WSDL’. In SoapUI (an extraordinary free application to test web services by the way) I created a project and imported this WSDL-file. Requests to try out are created by default. Double-click on one to open a new window and run it to send the request and receive the response. I had some initial problems that the address to connect to (specified in the wsdl-file) was set to localhost. This is easily fixed by editing the url in the request window. The address should be the web-address to the webservice, i.e. ‘http://domainname/aFolder/database/webServiceName?WSDL’.

Using this the SOAP-request looks like this:

<soapenv:Envelope xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:urn=”urn:DefaultNamespace”>
<soapenv:Header/>
<soapenv:Body>
</soapenv:Body>
</soapenv:Envelope>

This brings the problem that calling the method GetDbName or GetTest returns the same response, i.e. from the GetDbName method. The reason for this is that the method is not defined in the SOAP-request and therefore the first one is chosen.

What I did that made it work was simply to replace ‘Doc/literal’ as the SOAP message format to ‘RPC/encoded’. Maybe someone knows how to adjust something so that the correct WSDL-file is created from Lotus Notes when using ‘Doc/literal’ for this to work.

Exporting the WSDL-file with this setting makes the SOAP-request look like this instead. You can see that the method name is specificed in the body.:

<soapenv:Envelope xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:urn=”urn:DefaultNamespace”>
<soapenv:Header/>
<soapenv:Body>
<urn:GETDBNAME soapenv:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”/>
</soapenv:Body>
</soapenv:Envelope>

See how the web service is represented in SoapUI with all the methods.

And how the request window looks like for a method.

Finally here is the code for a lotusscript class with methods to return some statistics about a database. Download the WSDL-file here or generate it yourselves if you’d like:

Class DatabaseStats
Private session As NotesSession
Private db As NotesDatabase
Private nc As NotesNoteCollection

Public Sub New ()
Set session = New NotesSession
Set db = session.CurrentDatabase’
End Sub

‘ Return database name
Public Function GetDbName () As String
GetDbName = db.Title
End Function

‘ Return server name
Public Function GetServerName () As String
GetServerName = db.Server
End Function

‘ Returns number of documents in the database
Public Function GetNumDocuments () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectDocuments = True
Call nc.BuildCollection
GetNumDocuments = Cstr(nc.Count)
End Function

‘ Returns number of forms in the database
Public Function GetNumForms () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectForms = True
Call nc.BuildCollection
GetNumForms = nc.Count
End Function

‘ Returns number of views in the database
Public Function GetNumViews () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectViews = True
Call nc.BuildCollection
GetNumViews = nc.Count
End Function

‘ Returns number of agents in the database
Public Function GetNumAgents () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectAgents = True
Call nc.BuildCollection
GetNumAgents = nc.Count
End Function

‘ Returns number of shared fields in the database
Public Function GetNumSharedFields () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectSharedFields = True
Call nc.BuildCollection
GetNumSharedFields = nc.Count
End Function

‘ Returns number of pages in the database
Public Function GetNumPages () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectPages = True
Call nc.BuildCollection
GetNumPages = nc.Count
End Function

‘ Returns number of outlines in the database
Public Function GetNumOutlines () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectOutlines = True
Call nc.BuildCollection
GetNumOutlines = nc.Count
End Function

‘ Returns number of actions in the database
Public Function GetNumActions () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectActions = True
Call nc.BuildCollection
GetNumActions = nc.Count
End Function

‘ Returns number of folders in the database
Public Function GetNumFolders () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectFolders = True
Call nc.BuildCollection
GetNumFolders = nc.Count
End Function

‘ Returns number of script libraries in the database
Public Function GetNumScriptLibraries () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectScriptLibraries = True
Call nc.BuildCollection
GetNumScriptLibraries = nc.Count
End Function

‘ Returns number of profile documents in the database
Public Function GetNumProfileDocuments () As Integer
Set nc = db.CreateNoteCollection(False)
nc.SelectProfiles = True
Call nc.BuildCollection
GetNumProfileDocuments = nc.Count
End Function

End Class

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

3 comments

A limitation in Lotusscript Script Debugger

by Niklas Waller on October 7, 2008

in Lotus Notes Domino

I was debugging some code the other day and I needed to look at a field value before and after it had been set for a document. But it was not possible since there seems to be a limitation of how many fields that are displayed for a document in the debugger. In this case the number of items for a document.

The form that the document is based on contains 318 fields but the debugger can only list 256 items. After that it displays “…” to indicate that there is more. Ok, good to know, but I’d like to look at all fields. I assume that the same limitation goes for other objects in the debugger output listing.

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

1 comment

One thing that annoys me in Domino Designer 7

by Niklas Waller on September 27, 2008

in Lotus Notes Domino

If I open many databases in Domino Designer they all come up as bookmarks on the left-hand side. Sometimes If they are more than up to about 4 or 5 I cant expand the ones below, i.e. on the 5th position or more. I have to move them up so that they are on the 1-4th position. This morning when I started Notes I didn’t have this problem at all as I could easily expand all 7 seven bookmarks.

Why does this happen?

This could not be a special thing for just me since I have experienced it for as long as I remember on different machines and notes installations. Anyone agree or maybe have a good explanation?

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

1 comment

Count all fields in a Notes database

by Niklas Waller on September 20, 2008

in Lotus Notes Domino

I wanted to know how many fields there were in a Lotus Notes database. So here’s a small lotuscript for this. It counts all “real” fields (i.e. not Computed for display fields) on all forms and prompts the result. It doesn’t count unique fields however so if you make a copy of form A which have 10 fields 10 times the result is 100.

Sub Initialize
On Error Goto ErrorHandler
Dim session As New NotesSession
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase

Dim dbInfo As Variant
Dim sDbServer As String
Dim sDbPath As String

Dim countFields As Long

dbInfo = ws.Prompt(13, “Choose database”, “Choose a database”)
sDbServer = dbInfo(0)
sDbPath = dbInfo(1)

Set db = session.GetDatabase(sDbServer, sDbPath)

countFields = 0

Forall form In db.Forms
Forall field In form.Fields
countFields = countFields + 1
End Forall
End Forall

Msgbox Cstr(countFields)

Exit Sub
ErrorHandler:
Msgbox Error$ & ” on line ” & Cstr(Erl) & ” in ” & Lsi_info(12)
Exit Sub
End Sub

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

Be the first to comment

I wish I could be with you Lotusphere

by Niklas Waller on September 6, 2008

in Lotus Notes Domino

I attended Lotusphere 2006 when i was working at an animal insurance company in Sweden who uses Lotus Notes. I came there alone both as a developer, administrator and a company representative (well I actually knew a few people). And was I impressed? Wow, it was really, really good and I was amazed.

Cool general opening sessions, very good technical sessions all days long To be able to talk to experts/developers and people around you all over the place that have something in common, good arrangements and great dinner and parties at night.

I was suppose to go in 2007 as well but I changed employer so unfortunately I couldn’t and unfortunately I don’t think I will be able to go for a couple of years now either. But for all of you that have not been there and are going I congratulate you, you will have lots of fun and learn many new things and of course make new friends and perhaps new colleagues.

This is probably not new information to anyone on Planet Lotus but for anyone else that might land on this blog, here is a link to the site on IBM about Lotusphere 2009 where you can read about it and register.

Thomas Adrian did some calculation on his Twitter and stated that it would cost about 29000 swedish crowns. GAAAH! Not something I am doing with my own checkbook. But I also realize that for a great event like this it has to cost although a great part of it actually is the travel and staying.

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

2 comments

Validate email-addresses in Domino with Java

by Niklas Waller on September 2, 2008

in Lotus Notes Domino

It’s easy to validate an email address for a web application in JavaScript with the help of regular expressions since JavaScript follow the standards. When you need to do the same for a notes application you are either stuck with the @ValidateInternetAddress-formula or a hack to be able to use it in lotusscript (with evaluate) or by creating a VBScript RegEx object (I haven’t looked into this myself but it seems to be powerful).

Apart from this the regular expression functionality in lotusscript actually doesn’t exist except the like operator which do have some of the basic functionality of regular expressions but not enough for more advanced checks – like email validation.

One way of accomplishing it rather painless is to create a java agent that does the check since also Java support the standards of regular expressions. What you need is basically the java.util.regex package.

In my application I have created a Java script library with different methods to use for washing data but I will present only this function here in a simple Java agent to demonstrate. Remember that if you really must use lotusscript to run the code and the check you can call java objects from lotuscript. I haven’t tried it myself yet but here is a link.

Just paste the following code into a new java-agent, select “None” as runtime-target and run and you’ll see the result in the Java Debug Console.

import lotus.domino.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavaAgent extends AgentBase {

/**
* Constant regular expressions.
* The separation of the string below is only for the blog entry to display correct.
* You will of course not need it when running the code.
*/
public final static String EMAIL_REGEX = “^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*" + "+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?”;

/**
* @param Regular expression
* @param Pattern to check against the regular expression
* @return True if the pattern is valid against the regular expression and else false
*/
public boolean isValidString(String sRegEx, String sCheckPattern) {
Pattern p = Pattern.compile(sRegEx);
Matcher m = p.matcher(sCheckPattern);
return m.matches();
}

public void NotesMain() {

try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();

if (isValidString(EMAIL_REGEX, “an.address@test”)) {
System.out.println(“Valid email address!”);
} else {
System.out.println(“Invalid email address!”);
}

} catch(Exception e) {
e.printStackTrace();
}
}
}

This is compared to other solutions a small amount of code and pretty easy to understand and besides this it covers 99,99% of all email addresses in actual use today according to Regular-Expressions.info.

The ultimate and fail-proof official standard (RFC 2822) is extremely long and complex.

but you’re recommended not to use it.
Read more about this on the provided link above to regular-expressions.info.

Share and Enjoy:

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • email
  • Google Buzz
  • RSS
  • Slashdot
  • Technorati
  • Add to favorites
  • DZone
  • LinkedIn
  • MySpace
  • Tumblr

Be the first to comment