Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Blogs

photo

Yellow is the...

55 Entries |  Tim Tripcony
Updated 
No Ratings 0     Comments 22
photo

TexasSwede

66 Entries |  Karl-Henry Martinsso...
Updated 
No Ratings 0     Comments 59
photo

Lotus Nut

69 Entries |  Chris Whisonant
Updated 
Ratings 4     Comments 96
photo

Urs Meli

19 Entries |  Urs Meli
Updated 
No Ratings 0     Comments 14
photo

Uh Clem's Adm...

35 Entries |  Chris Mobley
Updated 
Ratings 5     Comments 42

Dogear Bookmarks

.Domino Framework

Blog Authors:  Peter Presnell  

All entries tagged with programming

NotesURL and Resolve

Peter Presnell  |     |  Tags:  inspector programming .dominoframework notesurl  |  Comments (0)

NotesURL  is a property available for the NotesSession, NotesDatabase, NotesView, NotesForm, NotesAgent, and NotesDocument classes.  It was one of those properties I had never really paid much attention to.  That was before I found myself needing to pass references to Notes objects from one application to another.  It is not the only way to pass references to these objects but it is perhaps one of the simplest to implement and is consistent across each of thes objects.

 

At the other end, the NotesSession class has a Resolve method.  This is basically the reverse of NotesURL, taking the URL and converting it back into an object (it also works with HTTP URLs too!).

 

So lets take the scenario in which a Services Oriented Architecture (SOA) is being built.  One application (Notes database) provides one or more services to other applications.  These services could operate against a database, view, document etc.  To invoke the service I need to provide a failsafe way to provide details about the database/view/document against which the service operates.   I can pass this in a number of ways:-

  1. Save the NotesURLs as environment variables in the Notes.INI
  2. Create a document in the other database with the NotesURL(s) placed inside a field
  3. Invoke a Web service (increases the ability for Non-Notes applications ualso using the service)

The alternatives for a NotesDatabase include servername and filpath, or replicaid.  Server/filepath requires two parameters to be provided or an artificial way to combine these together.  Replicaids represent a single string but lack the ability to designate a specific server (I may have made a change to a document on one server which has not replicated to other servers and hence the serice may not operate against the latest data if it uses another replica).

 

Views are more difficult to define as the only other standrad way to access a view in LS is via NotesDatabase.GetView.  This requires the name or alias of the view and this is not guaranteed to be unique.  Plus I need to make sure the parent database is also known.  NotesURL and Resolve gives us a way of ensuring the exxact same view is used within the service.

 

NotesDocumehts have a DocumentUNID that serves us well, but again we need to provide a reference to the parent database for this to work.  The NotesURL gives us all this information in a single string.

 

Note: It is also possible to serialize a NotesDocumentCollection by passing an array of NotesURLs.  This is a litlle messier as more code is needed on the other side to reconstruct the NotesDocumentCollection.

 

I have used the above in the latest beta of the .Domino Framework to implement the new Inspector tool.  This tool will provide a "magic button" to view/edit the attributes of the current database, document collections, and document.  The code for all this to work resides in the .Domino Framework template.  To get this service to work against any database (regardless of whether it implements the framework or not) I have devised a ToolBar button that will save details about the currenty database, view, document etc. and pass them to the Inspector tool via Notes INI variables.  For applicatuions that implement the framework the ablity to pass information about the currently selected documenyts ina view is added without using Notes.INI variables.  Because this is a Notes 6.0 framework I have not (yet) developed a Web Service option.

 

The .Domino Framewokr has also been expanded so that the constructors for the DominoDatabase, DominoView, DominoDocumentCollection, and DominoDocument classes can take a NotesURL as a parameter for the constructor.

 

Notes: Because the object refered to by a NotesURL can represent any one of the supported Notes classes it is sugessted that it be resolved into variant first.  Invalid NotesURLs throw an eror so it is also necessary to set the apporpriate error trapping to handle this.

 

Example: The following code is the DominoDocument class to locate a document using a key that could represent a NotesURL, HTTP URL, NoteID, or DocumentUNID.

 

'/**
 ' *  Locates an existing document based upon the document's key
 ' * @param Key  Key that can be used to locate the existing document (NoteID, UNID, Notes URL or HTTP URL)
 ' */ 
 Sub GetByKey(Key As String)
  Dim NotesObject As Variant
  
  On Error Resume Next        ' Prevent error if key is not a a valid NotesURL
  If Ucase(Left(Key,Len(STRING_NOTES_PROTOCOL_PREFIX))) = STRING_NOTES_PROTOCOL_PREFIX Or _
  Ucase(Left(Key,Len(STRING_HTTP_PROTOCOL_PREFIX))) = STRING_HTTP_PROTOCOL_PREFIX Then
   Set NotesObject = Session.Resolve(Key$)
   If NotesObject Isa "NotesDocument" Then
    Set iDocument = NotesObject
    Exit Sub
   End If
  End If
  Select Case Len(Key)
  Case 8  ' Possible NoteID in LS format
   Set iDocument = DB.GetDocumentByID(Key$)
  Case 9  ' Possible Note ID in @Language format
   Set iDocument = DB.GetDocumentByID(Left(Key$,8) + Right(Key,8))
  Case 32 ' Possible UNID
   Set iDocument = DB.GetDocumentByUNID(Key$)
  End Select
  Exit Sub
 End Sub

Defensive Programming

Peter Presnell  |     |  Tags:  .dominoframework programming  |  Comments (1)

Defensive programming involves writing code in such a way as to handle unforseen circumctances.   Too often when I look at code that is developed for Notes applications I see little or no evidence of defensive programming being used.

Notes applications more than any other of the major development platforms cries out for defensive programming.  Unlike SQL-based databases, Notes databases do not have a data schema and hence do not require that every document (row) contain the same finite list of fields (columns).  Nor does Notes require that each field (column) be of the same data type.  Notes fields also do not restrict if it can represent a single value or a list.  So there is always the real risk that the data may not contain what you expect.

As an example, lets look at an employee record which has an EmployeeNo field.

The following LotusScript code could result in an error for for many reasons:-

 

EmpNo = Doc.EmployeeNo(0)

  1.  The variable Doc may not yet be instantiated (i.e. be connected to an existing Notes document)
  2. The field EmployeeNo may not exist in the current document
  3. The value inside the EmployeeNo may not be of the same type as the variable EmpNo.  (it is not even clear from the code whether EmpNo is text or a number.
  4. Unlikely, but should EmployeeNo ever become a method or a property of the NotesDocument class then the code would no longer work.

The following alternative code protects us from many of the above potential problems.

 

If Not Doc Is Nothing Then

  If Doc.HasItem("EmployeeNo" ) Then

    EmpNo$ = CStr(Doc.GetItemValue("EmployeeNo" )(0))

  End If

End If

  1. We are making sure that we have a Notes document
  2. We are making sure the document has an EmployeeNo field
  3. We have made it clear in the code that we are expecting a string (The $ in EmpNo$ causes LotusScript to make sure EmpNo has been declared as a String)
  4. We are making a reasonable (but not complete) effort to convert any non-text values to a text value (assuming the values should be text).  i.e. This works for numbers or dates but would fail for a Rich Text field.

This of course results in a lot of extra code being required each and every time you attempt to access the contents of a Notes field.  Which probably expains why people often don't bother!!!

Another approach that can result in a reduction in the amount of code required and making the code easier to follow is to adopt Object Oriemted Programming techniques to make EmployeeNo a property of an Employee Class

Class Employee

  Property Get EmployeeNo$ As String

    If iDocument Is nothing Then Exit Property

    If iDocument.HasItem("EmployeeNo$) Then EmployeeNo$ = Cstr(iDocument.GetItemValue("EmployeeNo" )(0))

  End Property

End Class

Now each time I need to access the EmployeeNo field in my application I can write the code as

EmpNo$ = Employee.EmployeeNo$  or  If Employee.EmployeeNo$ <> "" Then

You will notice within the .Domino Framework that this technique is used repeatedly, especially when using the DominoDOcument class and extensions of that class.  The .DominoFramework also provides a property generator tool that automatically generates the LotusScript code for a property based upon the property name, notes field name, and the intended data type.  This takes a lot of the hack work out of creating all the property definitions needed when creating a new class.

 

Note: The above is but one of many defensive proramming techniques that could be employed.  In many cases it comes down to personal preference, coding style and/or coding standards.


Skip to main content link. Accesskey S
IBM Lotus Connections Help Tools About

Tags

A tag is a keyword that is used to categorize an entry. To view the entries with a particular tag, click a tag name or enter a tag in the box.
The tag cloud indicates the frequency of tag use. Popular tags appear darkest. The slider control adjusts how many tags are displayed in the tag cloud.