Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Blogs

photo

Yellow is the...

54 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  

Main  | Next

Improving The Performance Of Subforms

Peter Presnell  |     |  Tags:  performance subforms  |  Comments (3)

I have been working on an application that has a rather complicated form that includes three embedded subforms.  QA testing on unrelated enhancements identified performance issues with this form.  The current production release would load documents with this form in 3 seconds.  The new QA build would load documents with this same form in 30 seconds.  After as series of tests it was found that the subforms were causing the slow perfromance (e.g. taking the fields on the subforms and pasting them into the form made it run much faster).  I did some research and found the following blog suggesting that adding a Print "" statement to the initialize module of the subform.  Sure enough when I did this, my documents were again loading in 3 seconds.  Further testing showed that almost any LotusScript code could be added and have the same effect. 

I settled on adding a Stop statement as this seemed to have less impact on the application.  Subforms are known to have an exponential impact on performance when the number used starts to get large.  But having seen this with just three subforms I am now tempted to add a Stop statement in the Initialize module of ALL my subforms from now on to improve the performance.  It is somewhat ironic that Stop means Go!!

DominoDatabase.HasRole Property

Peter Presnell  |     |  Tags:  .dominoframework roles  |  Comments (0)

One of the things I find I am often doing in creating business logic for an application is determining if the curtrent user has a specific role.  I have just added the following HasRoles property to the DominoDatabase class inside the .DOmino Framework as a way of quickly if a user has a specific role:-

'/** ' * Determine if specific user has a particular role for this database ' */ Property Get HasRole(pUserName As Variant,pRole As String) As Boolean Dim Username As String Dim UserRoles As Variant Try: On Error Goto Catch If(iDB Is Nothing) Then Exit Property Select Case Typename(pUsername) Case "STRING" If (pUserName = "") Then UserName$ = Session.UserName$ Else UserName$ = Cstr(pUserName) Case "NOTESITEM" UserName = Cstr(pUserName.Values(0)) Case Else UserName$ = Session.UserName$ End Select UserRoles = iDB.QueryAccessRoles(UserName$) Forall UserRole In UserRoles If Cstr(UserRole) = pRole Then HasRole = True Exit Property End If End Forall HasRole = False Exit Property Catch: Stop Call ReportError() Exit Property End Property

@GetFile & @GetFileContents

Peter Presnell  |     |  Tags:  .dominoframework files  |  Comments (0)

The 0.6 Beta of the .DominoFramework already included a LotusScript implementation of the hypothetical @GetFile function.  This provides a shortuct to request the operating system to prompt the  user to select a file from the operating system using an undocument option of the NotesUIWorkspace.Prompt method:-

'/**
' * Prompts user to select a OS file using undocumented UIW.Prompt option
' *
' * @author Peter Presnell
' * @param  Default File Initial file name 
' * @return  Name of selected file (empty if cancel selected)
' */
Function atfGetFile(DefaultFile As String) As String
 Dim Title As String
 If DB Is Nothing Then Title$ = ".Domino Framework" Else Title$ = DB.Title$
 atfGetFile$ = Cstr(UIW.Prompt(12,Title$,"",DefaultFile$))
End Function

The next release of the .Domino Framework will also provide an implementation of the hypothetical @GetFileContent function.  This function can either take a filename as a parameter or prompt the user for a filename and then returns the contants of that filename in a NotesStream.  Again it acts as a shortuct way of getting the contents of a file without the need to repeat the LotusScript code to do this.

'/** ' * Reads the contents of a nominated file ' * ' * @author Peter Presnell ' * @param Source NAme of file to be read (Where non is provided the user is prompted to provide the file name) ' * @returns NotesSTream containing the contents of the file ' */ Function atfGetFileContent(Source As Variant) As NotesStream Dim FileName As String ' Name of file whose content is to be read Dim FileNum As Integer ' File number Dim Text As String ' Line of text read from file Try: On Error Goto Catch If Session.IsOnServer Then Exit Function Set atfGetFileContent = Session.CreateStream() Select Case Typename(Source) Case "STRING" If FileName$ = "" Then FileName$ = atfGetFile("") Else FileName$ = Cstr(Source) Case Else FileName$ = atfGetFile("") End Select If (FileName$ = "") Then Exit Function FileNum% = Freefile() Open FileName$ For Input As FileNum% Do While Not Eof(FileNum%) Line Input #FileNum%, Text$ Call atfGetFileContent.WriteText(Text$,EOL_CRLF) Loop atfGetFileContent.Position& = 0 Goto Finally Catch: Stop Call ReportError() Resume Finally Finally: If (FileNum% <> 0) Then Close FileNum% End Function

DominoDocument.XML

Peter Presnell  |     |  Tags:  xml .dominoframework  |  Comments (0)

The next release of the .Domino Framework will contain two new properties for the DominoDocument class.  The XMLStream property will provide an XML/DXL representation of the document as a Notes Stream (2GB limit).  The XML property will provide a XML/DXL representation of the document as a String (64K limit).  Because the DominoDocument design class extends the DominoDocument class these two properties will also provide XML representations of Design documents.

Note: Notes does not yet provide full fidelity for representing Notes document as DXL.  The above properties carry these same limitations.

'/** ' * XML (DXL) Representation of document ' */ Property Get XML As String Dim XMLStream As NotesStream If (iDocument Is Nothing) Then Exit Property Set XMLStream = Me.XMLStream XMLStream.Position = 0 If (XMLStream.Bytes < 2^16) Then XML$ = XMLStream.ReadText() End Property '/** ' * XML (DXL) Representation of document in the format of a NotesStream ' */ Property Get XMLStream As NotesStream Dim Exporter As NotesDXLExporter Dim XMLInputParser As NotesXMLProcessor Try: On Error Goto Catch If (iDocument Is Nothing) Then Exit Property Set XMLStream = Session.CreateStream() Set Exporter = Session.CreateDXLExporter(iDocument,XMLStream) Call Exporter.Process() Exit Property Catch: Stop Exit Property End Property

Extending a Java Class With LotusScript

Peter Presnell  |     |  Tags:  java lotusscript .dominoframework  |  Comments (0)
In a recent blog I documented a new DominoBES class that has been added to the .Domino Framework.  Due to a current limitation with LotusScript , this class had to be written in Java.  After doing some experimentation I found a way of abstracting the Java Implementation of the class by "extending" the Java class with a LotusScript class.  In theory this allows me to not only publish a Java class as a LotusScript class but to extend the Java class with additional methods/properties developed using LotusScript.
Why bother?  For one thing it is typically not a good idea to mix and match programming languages in an application as code maintenance then requires a developer with multiple programming language skills.  For another, at the site where I am making use of this class there are about 30 full-time Notes developers and several hundred part-time Notes "developers", almost none of whom program in Java.  By choice I am developing the .Domino Framework using LotusScript  wherever I can and using Java where it makes sense to do so because the pool of Note LotusScript developers greatly exceeds the pool of Notes Java developers. 
The following is the code that can be found in the latest beta version of the .Domino Framework for extending the DominoBES class. (Note: I believe both the LotusScript and Java classes can have the same name)
Option Public
Option Declare
Uselsx "*javacon"
Use "base.Domino.MailServices.BES.java"
Use "Domino.Applications"

' C L A S S b a s e D O M I N O B E S ___________________________________________________________________________ C L A S S
'/**
' * Communication with BES Server
'*
' * @author Peter Presnell
' */
Class baseDominoBES As DominoBaseClass

Private JavaSession As JAVASESSION
Private JavaClass As JAVACLASS
Private DominoBESJava As JavaObject
Private MDSHost As String
Private MDSPort As Integer
'/**
' * Constructor
' */
Sub New(),DominoBaseClass("")
Dim ApplicationSettings As New DominoApplicationSettings(Nothing)

Set JavaSession = New JAVASESSION()
Set JavaClass = JavaSession.GetClass("DominoBES")
Set DominoBESJava = JavaClass.CreateObject()

MDSHost$ = ApplicationSettings.BESServer$
MDSPort% = ApplicationSettings.BESPort%

End Sub
'/**
' * Push a browser channel to a Blackberry device. Displays one of two icons on application menu that link to a designated URL opened in teh BB browser.
' *
' * @param Email The email name of the blackberry user
' * @param PushURL The URL to be launched when the icon is selected
' * @param UnreadIconURL URL for the icon to be displayed until the BB user selects the icon
' * @param ReadiconURL URL for the icon to be displayed after te BB user selects the icon
' * @param PushID A unique ID to represent this channel on the BB device
' * @param PushTitle Text displayed along with the icons for the channel
' */
Sub BrowserChannelPush(Email As String,PushURL As String, UnreadIconURL As String, ReadIconURL As String, PushID As String, PushTitle As String)
Call DominoBEsJava.browserChannelPush(MDSHost$,MDSPort%,Email$,PushURL$,UnreadIconURL,ReadIconURL,PushID$,PushTitle$)
End Sub

End Class

Viewing HTML Source on Blackberry Device

Peter Presnell  |     |  Tags:  html blackberry  |  Comments (0)

To view the source (HTML) code from your Blackberry browser use the following key sequence:-

<Alt><R><B><V><S>

XSLT Transformation Added To Inspector

Peter Presnell  |     |  Tags:  inspector .dominoframework xslt  |  Comments (3)

The 0.6 Beta of the .Domino Framework was published on OpenNTF on the weekend.  One of the last minute additions in this release is the abillity to access the XSLT/Skins feature of the .Domino Framework from within the Inspector tool.   The significance of this is that this the Inspector tool can be invoked against ANY Notes database.  So this tool now allows developers to apply XSLT transformations to design elements without the need to include any additional code in the applications themselves.  All the code (and XSLT) is held in the .Domino Framework database.

e.g. I frequently take on development for existing Notes applications in which the fonts used in forms an/views are inconsistent.  Using Inspector I can apply an XSLT from the .Domino Framework to all view/forms that change all fonts to Default Sans Serif saving me hours of manual (and boring) coding.

New DominoDatabase.ReplicaID Property

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

Earlier today Tim Tripcomy wrote a great article about Nexus, a new tool he has developed to allow databases to be assigned new replica ids.  After reading the article I decided to finally get around to adding a Read/Write ReplicaID property to the .Domino Framework's DominoDatabase class based upon this code.  (Thanks Tim, I remember seeing the breaking par code a long time ago and forgot where I had seen it).  I will also be updating the Inspector tool included with the fraemwork so that the replicaid becomes editable.  The code is as follows:-

'/** ' * Replica ID of database (NotesDatabase property is read-only) ' */ Property Get ReplicaID As String If (iDB Is Nothing) Then Exit Property ReplicaID$ = iDB.ReplicaID$ End Property Property Set ReplicaID As String Dim DB_Path As String*256 Dim hDB As Long Dim ReplicaInfo As DBReplicaInfo If (Len(ReplicaID$) < 16 Or Len(ReplicaID$) > 17) Then Exit Property ' ReplicaID must be 16 characters with optional ":" in the middle (as used by @formulae) If iDB Is Nothing Then Exit Property Call OSPathNetConstruct(0, iDB.Server$, iDB.FilePath$, DB_Path) API_Return_Code = NSFDbOpen(DB_Path, hDb) If (API_Return_Code <> 0) Then Exit Property API_Return_Code = NSFDbReplicaInfoGet(hDb, ReplicaInfo) If (API_Return_Code = 0) Then ReplicaInfo.ReplicaID.Byte(0) = Val("&H"+Right(ReplicaID$,8)) ReplicaInfo.ReplicaID.Byte(1) = Val("&H" + Left(ReplicaID$,8)) API_Return_Code = NSFDbReplicaInfoSet(hDb, ReplicaInfo) End If API_Return_Code = NSFDbClose(hDb) End Property

LS Version @WebDBName

Peter Presnell  |     |  Tags:  .dominoframework lotusscript  |  Comments (3)

The @WebDBName function provides a quick way to get a reference to the current database in a format that can be used as a URL.  I am working on an application that needed much the same thing except I needed a link to another Notes database.  I decided to create a LS equivalent of the @WebDBName function that takes a single parameter.  This parameter can be Nothing (current database), String (filepath of database) or a NotesDatabase object and returns the URL for that database.  This function will be added to the next release of the  Domino.@Functions namespace (possibly released on OpenNTF this weekend).

'/** ' * Returns the name of a Notes database encoded for URL inclusion. ' * ' * @author Peter Presnell ' * @param Source Database path - Nothing = current database ' */ Function atfWebDBName(Source As Variant) As String Dim Filepath As String Select Case Typename(Source) Case "NOTESDATABASE" FilePath$ = Source.FilePath$ Case "STRING" FilePath$ = Cstr(Source) Case "OBJECT" FilePath$ = Session.CurrentDatabase.FilePath$ End Select atfWebDBName$ = atfReplaceSubstring(FilePath$,Split("\\: ",":"),Split("/:%20",":")) End Function
Note: In some cases an alternative to the above could be to use the NotesDatabase.HttpURL property.
The code for the atfReplaceSubstring (LS version of @ReplaceSubstring) is as follows:-
'/** ' * Replaces specific words or phrases in a string with new words or phrases that you specify ' * ' * @author Peter Presnell ' * @param Source he string whose contents you want to modify. ' * @param Search A list containing the words or phrases that you want to replace. ' * @param ReplaceTo A list containing the replacement words or phrases. ' * @return The sourceList, with any values from fromList replaced by the corresponding value in toList. ' * If none of the values in fromList matched the values in sourceList, then sourceList is returned unaltered. ' */ Function atfReplaceSubstring(Source As Variant, Search As Variant, ReplaceTo As Variant) As Variant Dim Results As Variant ' Interim results Dim Index As Long Dim ReplaceToItem As Variant ' Replacement value for match Try: On Error Goto Catch If Isarray(Source) Then Redim Results(Lbound(Source) To Ubound(Source)) For Index& = Lbound(Source) To Ubound(Source) Results(Index&) = atfReplaceSubstring(Source(Index&),Search,ReplaceTo) Next Index& atfReplaceSubstring = Results Else atfReplaceSubstring = Source If Isarray(Search) Then For Index& = Lbound(Search) To Ubound(Search) If Isarray(ReplaceTo) Then If Index& > Ubound(ReplaceTo) Then ReplaceToItem = ReplaceTo(Ubound(ReplaceTo)) Else ReplaceToItem = ReplaceTo(Index&) End If Else ReplaceToItem = ReplaceTo End If atfReplaceSubstring = atfReplaceSubstring(atfReplaceSubstring,Search(Index&),ReplaceToItem) Next Index& Else ' Covert all parameters to strings If Isarray(ReplaceTo) Then ReplaceToItem = Cstr(ReplaceTo(0)) Else ReplaceToItem = Cstr(ReplaceTo) End If Source = Cstr(Source) Search = Cstr(Search) ' Locate each occurence of search item and replace with replacement item If Search <> ReplaceToItem Then While Instr(atfReplaceSubstring, Search) > 0 atfReplaceSubstring = Left$(atfReplaceSubstring, Instr(atfReplaceSubstring, Search) - 1) + ReplaceToItem +_ Right$(atfReplaceSubstring, Len(atfReplaceSubstring) - Instr(atfReplaceSubstring, Search) - Len(Search) + 1) Wend End If End If End If Exit Function Catch: Stop Call ReportError Exit Function End Function

DominoBES class

Peter Presnell  |     |  Tags:  java bes blackberry .dominoframework  |  Comments (0)
I am now in the process of extending the .Domino Framerwork to support the publishing of Notes applications on a Blackberry client.  A new DominoBES class has been added as a way of allowing Notes applications to communicate with a Blackberry device via the Blackberry Enterprise Server (BES).  Unlike the rest of the framework, this class has been developed in Java due to the need to send an HTTP POST request.  The first method - browserChannelPush (see below) provides a wrapper for executing a Channel Push, effectively adding an icon to the Blackberry device, which when selected invokes the nominated URL.

import java.net.*;
public class DominoBES
{
  public void DominoBES()
  {
  }
  public void browserChannelPush(String mdsHost, int mdsPort,String email,String docURL, String unreadIconURL, String readIconURL, String pushID, String pushTitle)
  {
    try
    {
      URL mdsURL =  new URL("http",mdsHost,mdsPort,"push?DESTINATION=" + email + "&PORT=7874&REQUESTURI=/");
      HttpURLConnection connection = (HttpURLConnection)mdsURL.openConnection();
      connection.setRequestMethod("Post");
      connection.setRequestProperty("X-RIM-Push-Type","Browser-Channel");
      connection.setRequestProperty("X-RIM-Push-Title",pushTitle);
      connection.setRequestProperty("X-RIM-Push-Channel-ID",pushID);
      connection.setRequestProperty("X-Rim-Push-Read-Icon-URL",readIconURL);
      connection.setRequestProperty("X-Rim-Push-Unread-Icon-URL",unreadIconURL);
      connection.setRequestProperty("Content-Location",docURL);
    }
    catch (Exception e)
    {
      System.err.println("Push failure");
      e.printStackTrace(System.err);
    }
  }
}

import java.net.*;
public class DominoBES
{
  public void DominoBES()
  {
  }
  public void browserChannelPush(String mdsHost, int mdsPort,String email,String docURL, String unreadIconURL, String readIconURL, String pushID, String pushTitle)
  {
    try
    {
      URL mdsURL =  new URL("http",mdsHost,mdsPort,"push?DESTINATION=" + email + "&PORT=7874&REQUESTURI=/");
      HttpURLConnection connection = (HttpURLConnection)mdsURL.openConnection();
      connection.setRequestMethod("Post");
      connection.setRequestProperty("X-RIM-Push-Type","Browser-Channel");
      connection.setRequestProperty("X-RIM-Push-Title",pushTitle)