Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Blogs

photo

Lotus Nut

59 Entries |  Chris Whisonant
Updated 
Ratings 4     Comments 91
photo

TexasSwede

53 Entries |  Karl-Henry Martinsso...
Updated 
No Ratings 0     Comments 52
photo

Yellow is the...

48 Entries |  Tim Tripcony
Updated 
No Ratings 0     Comments 14
photo

Uh Clem's Adm...

22 Entries |  Chris Mobley
Updated 
No Ratings 0     Comments 23
photo

Urs Meli

13 Entries |  Urs Meli
Updated 
No Ratings 0     Comments 4

Dogear Bookmarks

.Domino Framework

Blog Authors:  Peter Presnell  

Previous |  Main  | Next

Adding Blackberry Support

Peter Presnell  |     |  Tags:  blackberry .dominoframework  |  Comments (0)
Earlier this week I started work on my first project in which I need to specifically design a Notes application to support  Blackberry Devices.  To assist me with this I have started to extend the capabilities of the .Domino Framework.

The DominoWebSession class now has two additional properties DeviceType and DeviceModel.  DeviceType will return "Blackberry" when the document is being loaded from a Blackberry Device (Later I expect to add other PDA devices such as iPhone).  This property works by looking for the text "Blackberry" in the CGI variable HTTP_User_Agent.  The DeviceModel property will pass back the specific Blackberry model.  This property can potentially be used to identify the resolution and capabilities of the Blackberry device.
I have also added a CGI\PDA subform that adds fields for these two properties to the standard CGI variables often passed with Web pages.
I will also be adding general Blackberry specific development stuff to the knowledge base of the .Domino Framework wiki.  This includes the following table of screen resolutions (I couldn't find a resource where this is documented).

Model Name Resolution
9500 Thunder 360 x 480
9000 Bold 480 x 320
8800
320 x 240
8700
320 x 240
8300 Curve 320 x 240
8100 Pearl 240 x 260
7200
240 x 160
7100
240 x 260

Document Locking V

Peter Presnell  |     |  Tags:  .dominoframework documentlocking  |  Comments (0)
Getting document locking to work has been one of my toughest assignment as a Notes developer.   But I have finally gotten a solution that passed QA.  So further to my previous FOUR blogs on this topic I can add the additional insight for others strugging to make document locking work (I know a few Notes developers that just gave up)
  1. Don't allow provisional locks.  These are the locks that occur when the master lock server is down.  When this server is down it is like not having document locking at all.  Provisional locks can only be preveneted by coding EVERYTHING through LotusScript.
  2. Persistent temporary locks only work to a degree.  These are the locks that occur when a document is placed in edit mode.  With every application I have implemented document locking I have found documents popping up (usually 1-2 a week) that remain locked even after  the document has bee closed.  Users of these applications can become confused (and frustrated) about these locks and in some cases are unable to remove the locks themselves.  If you can leave with this annoyance it is a LOT easier to implemen this model.
  3. The only reliable way to get document locking (and unlocking) to work is to allow persistent permanent locks only.  These are the locks that are placed manually before the document is opened.
Implementing persistent permanent locking only is waaayyyy  more challenging.
  1. The document locking event always occurs before any form event has a chance to respond.  So you cannot intercept (and prevent) a document locking action.  All you can do is detect and respond to a document locking operation.
  2. Users with Manager level access to a database can overide an existing lock.  Unless care is taken these people can inadvertently destroy the integrity of the document locking process.
  3. After a document has been opened in edit mode it is not possible to differentiate between a permanent persistent lock and a permanent temporary lock.
In implementing a solution to the above I have now completely rewritten the logic for the DominoDocumentCollection.Lock and DominoDocumentCollection.UnLock methods.  These methods now make use of a 2nd field that is added to documents when they are locked.  This 2nd field helps to identify that a persistent permanent lock has been placed and who placed it.  The form events must now be programmmed to check for the presence of a lock holder and 2nd field before allowing editing of a document.   Additionally we can inspect the current usname against the lockholder and 2nd field to identify a Manager who has been able to lock the document without originally holding the permanent persisent lock.  When this happens you can chose to refuse the edit request and restore the lock back to orginal lock holder.
To the application users the process looks like this.  They must first place a lock on one or more documents.  This is done from relevant views via a view action and/or using an inviewedit process to toggle a lock icon by clicking on the relevant column in the view.  An icon is added to the views to show documents that are locked.  Locks do not work if the Master Lock Server is not available.  Lock holders can then edit the locked document(s).  When they are finished they must unlock the document.  An Administrator with Manager level access can unlock documents locked by others (at their own peril!).
A working example of this will be included as part of the next release of the .DominoFramework.
Note: With Notes 6.0 it is not possible to edit attachments where a lock already exists.  (This is not the case with Notes 8.0).  To get around this issue I have devised a 2nd form that can be used to edit attachments.  This form does not contain the event trapping to prevent a document being edited when locked.  To reduce the risk of persistent temporary locks remaining, these are always removed when the document is closed (i.e lockholder is present but 2nd field is absent).

Baking A Sharepoint Killer

Peter Presnell  |     |  Tags:  lotus_notes workflow sharepoint social_software documentmanagement  |  Comments (6)
For many years Microsoft have been trying to build a application capable to challenging Lotus Notes.   For just as many years Microsoft have been falling short in that effort.  Recently however I have began to notice that many of the organizations for whom I work Sharepoint is being considered as a solution for applications that would previously be the realm of Lotus Notes.  Could it be that Lotus Notes now does have a viable competitor?  It doesn't seem like it when you compare the products technically.  But hey, to this day I still feel that Lotus 1-2-3 was a superior spreasheet application to Excel and I preferred Netscape Navigator over Internet Explorer.  So who knows what the Microsoft marketing machine can convince senior IT executives.
As I see it, Sharepoint has a number of distinct weaknesses.  First, it still seems to have more hype than substance.  It is not as much out of the box as Microsoft would like us all to believe.  It is also not a single product, requiring the usual mismash of products such as Sharepoint Server, SQL Server, IIS, Visual Studio, Active Directory to work.  And it is a Windows only solution aimed solely at selling even more MS software....
If I had the resources of a company like IBM this is how I would go about baking a killer product capable of resigning Sharepoint to the same fate as the last "great white hope" - IBM Workplace.

1) The base product would continue to be Lotus Notes.  Nobody has ever come up with a product that can compete with Notes for the simplicity  of building and deploying collaborative applications.  Notes consists of a single NSF that contain all the data and code.  By adding integrated security, replication, directory services, and mail services the task of building and deploying an application onto multiple servers has never been made easier.  Add to that the new slick Notes 8.0 UI, composite applications and the as-yet untapped capabilities of X-Pages and you have a platform that is truly capable of rapidly delivering modern high quality SOA applications on both thick and thin client platforms.
2) One of the strength of Lotus Notes has always been the speed with which customized solutions can be developed.  The programming base of Notes does however need an urgent overall to bring it into the 21st century.  This includes completing the work already started to migrate Domino Designer to the Eclipse platform.  Java and LotusScript editors need to delivered quickly along with native eclipse editors for all the other non-xpages design elements.  The LotusScript language must be expanded to offer many of the capabilities found in Java (and VB.Net/C#).  Likewise IBM need to find a way to make  Java available in all the same places LotuScript can be used.  We then have a HUGE army of Basic (LotusScript) and java programmers able to fully leverage the product.
3) Sharepoints' current strengths over Lotus Notes include Document Management and Workflow.  I would turn this weakness into a strength by taking the Lotus Worklflow and Lotus Document Management products and integrating them into the standard Notes/Domino product.  These products have been neglected and are unable to effectively compete as stand-alone products.  It is often an impossible task to convince IT executives to approve the purchase of new products such as these.  But then, if they were part of the core Notes product I wouldn't have to.  I can't believe these products are huge contributors to the IBM bottom line.  If they were, they would get an occasional mention at LotusSphere (outside of appearing on the annual LotusSphere Bingo cards).
4) The out-of-the-box capabilities of Notes would need to be expanded to take on Sharepoint.  Enhanced document library and teamroom templates are needed that exploit the features of document management and workflow and build on some of the great ideas found in QUICKR (including the SNAPPS templates).  Added to that we need a killer blog template - perhaps taking the existing IBM blog template and combining that with the OpenNTF Blogsphere template.    A wiki template is needed - again the openNTF DominoWiki template is a great start.   We would also need to add to the mix some of the social software capabilities  found in Lotus Connections.  An improved PAB that adds some of the profiling capabilities of Connections and even a little sex appeal with something like Lotus911's Carousel.  For DogEars it would be hard to go past LinkJam - and why not throw in an idea/suggestion scheme template (IdeaJam).  For good measure some form of Activity management template is needed.  And while I am not a big twitter fan, a twitter template may not be a bad addition too.  Also build out the RSS Feed manager to be comparable with products such as FeedDemon.

Take the above ingredients and mix in a large yellow bowl until the right consistency is achieved.  Then add to a hot oven and allow to bake for 3-6 months.  Don't cook for too long now or Sharepoint will be selling like hotcakes and the juggernaut may become uncatchable.  Served to a large corporate audience I am sure this new Sharepoint Killer would soon get that yellow blood pumping through the veins of organizations around the globe.

DragDrop To A View

Peter Presnell  |     |  Tags:  views dragdrop folders  |  Comments (0)
By default Notes only supports the dragging/dropping of documents into a folder.  The following is a technique developed for an application allowing the simulation of dragging a collection of documents into a view:-
  • For each view to support drag/drop create a new (dummy) folder.  The design of the folder does not matter as it is never opened/used.
  • Modify any outlines used to link to the dummy folder instead of the original view
  • Place the following code into the QueryOpen event of each dummy folder forcing the associated view (or page with embedded single category view) to open instead of the folder when selected from the outline.
Sub Queryopen(Source As Notesuiview, Continue As Variant)
    Dim UIW As New NotesUIWorkspace
    Continue = False
    Call UIW.SetTargetFrame("NotesView" )
    Call UIW.CurrentDatabase.OpenView("Viewname" )
    or
    Call UIW.OpenPage("Pagename" )
End Sub

  • Modify the database's Postdragdrop event to evaluate continue = false, preventing documents being placed into these dummy folders.
  • Finally, add the code to the Postdragdrop event to perform the  desired task for a collection of documents being "dropped in the view".
 

Minimising Document Changes

Peter Presnell  |     |  Tags:  save edithistory .dominoframework  |  Comments (0)
I common problem I encounter when maintaining Notes applications is that documents are being saved multiple times as the result of a single event/action.  In some cases there may not have been any changes made to the actual data.  Reducing the number of times a document is  saved can generate a number of benefits to the application.
  1. Application Performance: The save operation is an expensive one. The fewer the number of saves, the faster the code runs.
  2. Server Performance: Each and every time a document is saved it creates the potential need for the server to update every view index to establish if the change has an effect on the view.  The server may also need to update the full text index.  If the data did not change this work results in no change (but the server doesn't know that!)
  3. Reduced Conflicts: A repeated number of saves can result in a save conflict being generated.  It also increases the chances of replication conflicts if the document is being edited on another server.
  4. Accurate Edit History:  The document history is updated each time the document is saved.  The date/time of the last change and the identity of the author is somehwat invalid if the actual data did not change.  The number of entries in the edit history can also become much larger than it needs to be if additional saves have been performed.
One of the main reasons for multiple saves is the difficulty of keeping track of when changes had been made.  e.g. each section of code does a save just in case the next code block doesn't do a save.  One of the way to minimize the number of changes is to keep track of whenever any item in a document has been changed and then only save the document if a change has been made (to one ore more items).  The .Domino Framework provides one potential solution.  Being  Object Oriented, the document-based classes maintain an internal iHasChanged variable that is initially set to false.  Each of the Property Set code blocks sets the iHasChanged variable to True.   The .Domino Framework Property Generator Tool provides the option to include this logic as part of the p[roperty code it generates.

e.g.
Property Get CompanyName As String
  If iDocument Is Nothing Then Exit Property
  If iDocument.HasItem("CompanyName" ) Then CompanyName$ = iDocument.GetItemValue("CompanyName" )(0)
End Property
Property Set CompanyName As String
  If iDocument Is Nothing Then Exit Property
  Call iDocument.ReplaceItemValue("CompanyName",CompanyName$)
  iHasChanged = True
End Property


It is then possible at the very end of a code block (e.g. event or action) to test to see if any changes have been made and only invoke a save when the variable has been set. 
Note: The framework's DominoDocument class has a Save event which supports the above by only saving the document if a change has been made (iHasChanges = true).  It also resets the flag after the save.
To further reduce the number of changes it is also suggested that comparisons be made with the existing value before updating the object's property.

e.g.
If Employee.CompanyName$ <> CompanyName$ Then Employee.CompanyName$ = CompanyName$
If Employee.Postcode$ <> Postcode$ Then Employee.Postcode$ = Postcode$

Using the above it is often possible to develop code that only needs to do a single save at the very end if, and only the values of at least one field have been changed.

Optimizing Database Lookups

Peter Presnell  |     |  Tags:  lotusscript  |  Comments (2)

It is a common feature of an application to perform lookups into a view to locate a document based upon one or more keys.  The following are some tips for optimizing the LotusScript code when there may be a large number of lookups being performed (e.g. running against all selected documents in a view or all documents in a database).

 

1) Code the view name as a constant so that it is easier to maintain (and read) the code

2) Make the view static.  For OOP define a private variable in the class for the view.  For procedural code define a static function.

3) Fetch the view from that database once only by checking to see if the view is "Nothing"

4) To locate documents that have been created after the view was last refreshed it is usually more efficient to do a search first and then refresh the view (and research) only if the initial search failed than to refresh the view first every time.

 

Procedural Code:-

 

Static Function getByKeys(Source As variant) As NotesDocument

Dim iView as NotesView

If iView Is Nothing Then Set iView = DB.getView(MY_VIEW_NAME)
  If iView Is Nothing Then Exit Function
  Set getByKeys = iView.GetDocumentByKey(Source)
  If getByKeys Is Nothing Then
   Call iView.Refresh
   Set getByKeys = iView.GetDocumentByKey(Source)
  End If

End Function

 

OOP Code:

 

Class MyClass

Private iView As NotesView

Function getByKeys(Source As variant) As NotesDocument

If iView Is Nothing Then Set iView = DB.getView(MY_VIEW_NAME)
  If iView Is Nothing Then Exit Function
  Set getByKeys = iView.GetDocumentByKey(Source)
  If getByKeys Is Nothing Then
   Call iView.Refresh
   Set getByKeys = iView.GetDocumentByKey(Source)
  End If

End Function

End Class

History Of LotusScript - Part 3

Peter Presnell  |     |  Tags:  lotusscript .dominoframework vb oop  |  Comments (1)

LotusScript is a dialect of the BASIC programming language.  Version 1.0  of LotusScript was released in 1993 as part of a new spreadsheet product called Lotus Improv.  LotusScript 2.0 added the ability to work with Notes applications and formed part of Lotus Visual Programmer (ViP).  ViP was designed as a competitor for Visual Basic, which had been released by Microsoft in 1991.   ViP was eventually discontinued as a stand-alone product and we saw LotusScript 3.0 added to Notes 4.0 in January 1996.  At this time LotusScript required the use of the "C API" to access Notes data.  In October 1996 Microsoft launched VB4,adding the ability to define custom classes, effectively making BASIC an Object Oriented Programming language.  In December 1996 Notes 4.5 was released adding the ability to create LotusScript libraries and providing 26 product classes that allowed direct access to Notes data.  At this time both Visual Basic and LotusScript were comparable products.  As discussed  last week in Part 1 Lotus/IBM continued to provide significant enhancements to the LotusScript language as part of Notes R5 (1999) and Notes 6.0  (2002).

In April 2003 the landscape of BASIC programming changed when Microsoft introduced VB.Net as part of its .Net Framework.  A new programming language (C#) was also developed as part of the .Net framework, but Microsoft also updated its VB language to allow devoted BASIC programmers an easy way to migrate to its new development platform.  This stragey seemed to work.  In Part 2 I contrasted the approach being taken by IBM who seemed to focus its effort post 6.0 on building a competing product for Lotus Notes called IBM Workplace.  Notes 8.0 provided some extensions but Notes 8.5 now looks like being the first release of Notes in which no extensions of the LotusScript language are provided and the promised Eclipse LotusScript Editor is also missing.  This is all comes despite the fact that LotusScript remains the core programming language for most Notes development.  Java has now been added as an alternative but it is still not implemented fully and does not have the same following as LotusScript.

I blogged last month about some of the things I would like to see added to the LotusScript language.  Many of these have been posted by me and others on IdeaJam But whilst there is little that can be done to extend the LotusScript language, the good news is that we as Notes developers can use the LotusScript language that we already have to fill in many of the gaps that exist in the product classes such as NotesDatabase and NotesDocument.  This uses the Object Oreinted Programming capabilities of Lotuscript to extend the existing product classes allowing us to add new properties/methods and even create new classes.  The following techniques will work for Notes 4.5+.

1) LotusScript Library
Create one (or more) LotusScript Libraries to hold your code.  Options include having one LotusScript library for all the new classes, or having a separate LotusScript library for each class.  The new classes can then be introduced to your Notes application via the Use statement.
Examples:
Use "BleedYellow" or Use "BleedYellow.BleedYellowDocumentCollection"

2) Create New Classes
Create one or more new classes.  It is suggested you chose names for your new classes that are derived from the product class being "extended" (e.g. DominoDocument, NotesDocument2, SuperNotesDocument).  Because LotusScript presently does not allow us to extend product classes directly we need to create new classes from scratch that include rather than extend the base class.

Example:
The NotesDocumentCollection class could be extended as follows:-

Class BleedYellowDocument Collection

  Public Documents As NotesDocumentCollection

  Sub New(Source As NotesDocumentCollection)
    Set Documents = Source
  End Sub

End Class


Note: If LotusScript supported direct extensions of product classes the above code could effectively be replaced with:-
Class BleedYellowDocumentCollection As NotesDocumentCollection
End Class

3) Make Base Object A Property
While the example above works, OOP principals require that Properties be used instead of exposing public variables directly.  This allows you the ability to wrap additional logic around the object at any time, such as validation, without exposing any changes in the interface to consumers of the class.

Class BleedYellowDocument Collection
  Private iDocuments As NotesDocumentCollection
  Sub New(Source As NotesDocumentCollection)
    Set iDocuments = Source
  End Sub
  Property Get Documents As NotesDocumentCollection
    Set Documents = iDOcuments
  End Property
 
Property Get Documents As NotesDocumentCollection
    Set iDocuments = Documents
  End Property
End Class

4) Extend The Constructor
One of the first extensions that can be applied to a class is the options for the constructor.  By always making the single parameter to a the constructor a Variant it becomes possible to pass a wide range of objects to the constructor, including arrays and lists.  In a way this overcomes one of the weaknesses of LotusScript, the inability to overload a method.  The TypeName statement can be used identify the type of object being passed.

  Sub New(Source As Variant)

    Dim Doc As NotesDocument
    Select Case TypeName(Source)
      Case "NOTESDOCUMENTCOLLECTION"
        Set iDocuments = Source
      Case "NOTESDATABASE"

        Set iDocuments = Source.GetProfileDocCollection("passingkeythatdoesnotalreadyexist" )
      Case "NOTESVIEW"

        Set iDocuments = Source.Parent.GetProfileDocCollection("passingkeythatdoesnotalreadyexist" )

        Set Doc =  Source.GetFirstDocument
        While Not Doc Is Nothing
         Call iDocumentCollection.AddDocument(Doc)
         Set Doc = Source.GetNextDocument(Doc)
       Wend
      Case "NOTESDOCUMENT"

        Set iDocuments = Source.GetProfileDocCollection("passingkeythatdoesnotalreadyexist" )
        Call iDocuments.Add(Source)
      Case "OBJECT"

        Set iDocuments = Session.CurrentDatabase.GetProfileDocCollection("passingkeythatdoesnotalreadyexist" )
    End Select
  End Sub

 

Applying the above code....

Set Collection = New BleedyellowDocumentCollection(Nothing)            ' Create empty document collection in current database

Set Collection = New BleedyellowDocumentCollection(DB                    ' Create empty document collection in DB

Set Collection = New BleedyellowDocumentCollection(Doc)                    ' Create document collection with single document Doc

Set Collection = New BleedyellowDocumentCollection(DB.Document) ' Create document collection with all documents in database DB

Set Collection = New BleedyellowDocumentCollection(View)                  ' Create document collection with all documents in view View

 

5) Add New Properties/Methods
Build out your new class by adding additional properties/methods (Note: The OOP term Method = Sub/Function in LotusScript).  You can also rewrite the logic of the product class by adding code to the new extended class.

Example: A new Add method could be developed that provides a much wider range of options for what is added to the collection.  Passing a NotesView could add all document in that view to the collection.

Sub Add(Source As Variant)
  Select Case TypeName(Source)
    Case "NOTESVIEW"
.. code to add documents in view
  End Select
End Sub


6) Using The New Class
The properties/methods of the base class can be accessedd via the base object.  The new properties/ethods are accessed via the new class.

e.g.

Dim UIW As New NotesUIWorkspace
Dim Collection As BleedYellowDocumentCollection
Dim Favorites As NotesView

Set Collection = New BleedYellowDocumentCollection(UIW.CurrentView) ' Create collection with document selected in view
Call Collection.Document.Add(Doc) ' Adds document to collection using existing NotesDocumentCollection method
Call Collection.Add(Favourites) ' Adds all the document in the Favourites folder the the collection using the new enhanced Add method


.Domino Framework
The .Domino Framework provides a large number of examples of the above in practice.  A lot of the code is found in a LotusScript library base.Domino.Application.  This library provides 100s of new properties/methods for classes such as DominoDatabase, DominoView, DominoDocumentCollection, and DominoDocument.  You can use these classes directly or take parts of the code to build your own custom classes.  So don't just wait for IBM to take the lead, If you are not already doing so, start building your own custom classes to fill in the gaps needed by your applications.

History Of LotusScript - Part 2

Peter Presnell  |     |  Tags:  lotusscript  |  Comments (1)

Yesterday I documented the changes introduced to LotusScript with Notes 6.0 and the momentum the language had at that time. 

Today I wish to jump forward to the next release of Notes - Notes 8.5.  The release notes suggest that Notes 8.5 has two new LotusScript statements and 4 new methods/properties being added to existing classes.  This blog entry is going to be shorter than I originally thought, because on checking further, it turns out that all of these LotusScript extensions are in fact documented as being part of the 8.0 release.   So as it stands, Notes 8.5 will be the first release of Notes in which not a single extension of the language is provided.  Even in the dark days of Notes 7.0/IBM Workplace we were still able to get something.

Note: A more complete history of LotuScript since Note 4.0 is included in the .Domino Framework wiki.  The following is a summary from the wiki showing the number of extensions made to the LotusScript language since Notes 4.0:-

Release LS Extensions New Classes New Methods/Properties
Notes 4.0     ? n/a n/a
Notes 4.5 ? 26 n/a
Notes 4.6 ? 1 6
Notes 5.0 13 8 107
Notes 6.0 9 40 181
Notes 6.5 0 0 35
Notes 7.0 0 0 17
Notes 8.0 2 4 45
Notes 8.5 0 0 0

History Of LotusScript - Part 1

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

A large part of the .DominoFramework involves extending the base LotusScript classes provided by Notes such as NotesDatabase, NotesDocumentCollection, and NotesDocument.  Extensions that I would hope one day may be included as part of that next great release of Notes.  You know the one, the one where IBM show their renewed support for Notes client development and the LotusScript programming language!

 

To keep track of all the features already available within LotuScript I have started compiling a history of the LotusScript language.  It is proving to be an interesting exercise.  The last Notes release I got excited about (as a Notes client developer) was 6.0.  And now I can see why... That release contained 9 new LotusScript statements, 40 new LotusScript classes, and 181 new properties/methods for existing classes.  Pretty impressive really, and shows the priority, focus, and direction IRIS (RIP) was providing for LotusScript at the time.  Note: Much of the work started with the 6.0 release (DXL, InViewEdit, NotesRichText, CSS for forms/pages, Document Locking) has still never been finished off 6 years later.  For those of you that may be interested, I have listed these language extensions below.  (Hence this will is a lengthy blog, but tomorrow's blog should be much smaller when I list the new LotusScript features coming in Notes 8.5).

 

 New LotusScript Statements (9)
* Boolean datatype
* CBool function
* Byte datatype
* CByte fundtion
* Implode function
* Join function
* Replace function
* Split function
* StrToken function

 

New Classes (40)
* NotesAdministrationProcess
* NotesColorObject
* NotesDOMAttributeNode
* NotesDOMCDATASectionNode
* NotesDOMCharacterDataNode
* NotesDOMCommentNode
* NotesDOMDocumentFragmentNode
* NotesDOMDocumentNode
* NotesDOMDocumentTypeNode
* NotesDOMElementNode
* NotesDOMEntityNode
* NotesDOMEntityReferenceNode
* NotesDOMNamedNodeMap
* NotesDOMNode
* NotesDOMNodeList
* NotesDOMNotationNode
* NotesDOMParser
* NotesDOMProcessingInstructionNode
* NotesDOMTextNode
* NotesDOMXMLDeclNode
* NotesDXLExporter
* NotesDXLImporter
* NotesMIMEHeader
* NotesNoteCollection
* NotesReplicationEntry
* NotesRichTextDocLink
* NotesRichTextNavigator
* NotesRichTextRange
* NotesRichTextSection
* NotesRichTextTable
* NotesSAXAttributeList
* NotesSAXException
* NotesSAXParser
* NotesStream
* NotesUIScheduler
* NotesXMLProcessor
* NotesXSLTransformer

 

New Methods/Properties (181)
* NotesACL.AdministrationServer
* NotesACL.iSadminNames
* NotesACL.IsAdminReaderAuthor
* NotesACL.IsExtendedAccess
* NotesACLEnry.CanReplicateOrCopyDocuments
* NotesAgent.IsActivatable
* NotesAgent.HttpURL
* NotesAgent.Lock
* NotesAgent.LockProvisional
* NotesAgent.LockHolders
* NotesAgent.NotesURL
* NotesAgent.OnBehalfOf
* NotesAgent.Unlock
* NotesDatabase.ACLActivityLog
* NotesDatabase.FileFormat
* NotesDatabase.FTIndexFrequency
* NotesDatabase.IsClusterReplication
* NotesDatabase.IsConfigurationDirectory
* NotesDatabase.IsCurrentAccessPublicReader
* NotesDatabase.IsCurrentAccessPublicWriter
* NotesDatabase.IsDesignLockingEnabled
* NotesDatabase.IsDocumentLockingEnabled
* NotesDatabase.IsInMultiDbIndexing
* NotesDatabase.IsInService
* NotesDatabase.IsLink
* NotesDatabase.IsPendingDelete
* NotesDatabase.LastFixup
* NotesDatabase.LimitRevisions
* NotesDatabase.LimitUpdatedBy
* NotesDatabase.ListInDbCatalog
* NotesDatabase.SizeWarning
* NotesDatabase.Type
* NotesDatabase.UndeleteExpireTime
* NotesDatabase.CompactWithOptions
* NotesDatabase.CreateFTIndex
* NotesDatabase.CreateNoteCollection
* NotesDatabase.CreateView
* NotesDatabase.Fixup
* NotesDatabase.FTSearchRange
* NotesDatabase.GetOption
* NotesDatabase.MarkForDelete
* NotesDatabase.QueryAccessRoles
* NotesDatabase.RemoveFTIndex
* NotesDatabase.SetOption
* NotesDatabase.Sign
* NotesDatabase.UnprocessedFTSearchRange
* NotesDatabase.HttpURL
* NotesDatabase.NotesURL
* NotesDocument.HttpURL
* NotesDocument.NotesURL
* NotesDocument.IsEncrypted
* NotesDocument.LockHolders
* NotesDocument.CloseMIMEEntities
* NotesDocument.CreateMIMEEntity
* NotesDocument.GetItemValueDateTimeArray
* NotesDocument.GetMIMEEntity
* NotesDocument.GetReceivedItemText
* NotesDocument.Lock
* NotesDocument.LockProvisional
* NotesDocument.RemovePermanently
* NotesDocument.Unlock
* NotesForm.HttpURL
* NotesForm.NotesURL
* NotesForm.LockHolders
* NotesForm.GetFieldType
* NotesForm.Lock
* NotesForm.LockProvisional
* NotesForm.Unlock
* NotesItem.GetValueDateTimeArray
* NotesMIMEEntity.BoundaryEnd
* NotesMIMEEntity.BoundaryStart
* NotesMIMEEntity.Charset
* NotesMIMEEntity.Encoding
* NotesMIMEEntity.HeaderObjects
* NotesMIMEEntity.Preamble
* NotesMIMEEntity.CreateChildEntity
* NotesMIMEEntity.CreateHeader
* NotesMIMEEntity.CreateParentEntity
* NotesMIMEEntity.DecodeContent
* NotesMIMEEntity.EncodeContent
* NotesMIMEEntity.GetContentAsBytes
* NotesMIMEEntity.GetContentAsText
* NotesMIMEEntity.GetEntityAsText
* NotesMIMEEntity.GetNextEntity
* NotesMIMEEntity.GetNthHeader
* NotesMIMEEntity.GetPrevEntity
* NotesMIMEEntity.GetPrevSibling
* NotesMIMEEntity.GetSomeHeaders
* NotesMIMEEntity.Remove
* NotesMIMEEntity.SetContentFromBytes
* NotesMIMEEntity.SetContentFromText s
* NotesSession.HttpURL
* NotesSession.URLDatabase
* NotesSession.Resolve
* NotesView.HttpURL
* NotesView.NotesURL
* NotesViewColumn.Parent
* NotesReplication.DontSendLocalSecurityUpdates
* NotesReplication.GetEntry
* NotesRichTextItem.AppendTable
* NotesRichTextItem.BeginInsert
* NotesRichTextItem.BeginSection
* NotesRichTextItem.Compact
* NotesRichTextItem.CreateNavigator
* NotesRichTextItem.CreateRange
* NotesRichTextItem.EndInsert
* NotesRichTextItem.EndSection
* NotesRichTextItem.GetNotesFont
* NotesRichTextItem.GetUnformattedText
* NotesRichTextItem.Update
* NotesRichTextStyle.IsDefault
* NotesSession.OrgDirectoryPath
* NotesSession.UserGroupNameList
* NotesSession.CreatAdministrationProcess
* NotesSession.CreateColorObject
* NotesSession.CreateDOMParser
* NotesSession.CreateDXLExporter
* NotesSession.CreateDXLImporter
* NotesSession.CreateSAXParser
* NotesSession.CreateStream
* NotesSession.CreateXSLTransformer
* NotesSession.GetUserPolicySettings
* NotesSession.HashPassword
* NotesSession.SendConsoleCommand
* NotesSession.VerifyPassword
* NotesUIDatabase.Close
* NotesUIDatabase.PostDropToArchive
* NotesUIDatabase.QueryDropToArchive
* NotesUIDocument.GetSchedulerObject
* NotesUIDocument.OnHelp
* NotesUIDocument.OnLoad
* NotesUIDocument.OnSubmit
* NotesUIDocument.OnUnload
* NotesUIDocument.PostSend
* NotesUIDocument.QueryRecalc
* NotesUIDocument.QuerySend
* NotesUIView.CalendarDateTimeEnd
* NotesUIView.CaretNoteID
* NotesUIView.ViewInheritedFrom
* NotesUIView.Close
* NotesUIView.DeselectAll
* NotesUIView.InViewEdit
* NotesUIView.PostEntryResize
* NotesUIView.QueryEntryResize
* NotesUIWorkspace.GetCurrentDatabase
* NotesUIWorkspace.ViewRebuild
* NotesUIWorkspace.ComposeDocument
* NotesUIWorkspace.DialogBox
* NotesView.EntryCount
* NotesView.IsProhibitDesignRefresh
* NotesView.LockHolders
* NotesView.SelectionFormula
* NotesView.ViewInheritedName
* NotesView.CopyColumn
* NotesView.CreateColumn
* NotesView.Lock
* NotesView.LockProvisional
* NotesView.RemoveColumn
* NotesView.SetAliases
* NotesView.Unlock
* NotesViewColumn.HeaderFontColor
* NotesViewColumn.HeaderFontFace
* NotesViewColumn.HeaderFontPointSize
* NotesViewColumn.HeaderFontStyle
* NotesViewColumn.IsFontBold
* NotesViewColumn.IsFontItalic
* NotesViewColumn.IsFontStrikethrough
* NotesViewColumn.IsFontUnderline
* NotesViewColumn.IsHeaderFontBold
* NotesViewColumn.IsHeaderFontItalic
* NotesViewColumn.IsHeaderFontStrikethrough
* NotesViewColumn.IsHeaderFontUnderline
* NotesViewColumn.IsNumberAttribParens
* NotesViewColumn.IsNumberAttribPercent
* NotesViewColumn.IsNumberAttribPunctuated
* NotesViewColumn.ResortToViewName
* NotesViewColumn.SecondaryResortColumnIndex
* NotesViewNavigator.Count
* ODBCConnection.ThreadSafeDriver
* ODBCResultSet.Connection

Document Locking

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

Document Locking continues to be a frustration for me to implement.  Despite all my best endeavours I have simply not been able to implement Persistent Temporary document locking with Notes 6.0 so that it works reliably.  I have in which it is important to ensure that (1) only one person can edit a document at any one time, (2) documents do not remain in a state where they remain locked by a person who is unable to remove the lock, and (3) no replication/save conflicts occur .  Unless soemone has a brilliant solution it seems the simplest way to achieve this is to supp[ort Persistant locks only in which the user must first lock the document manually, then edit the document, before releasing the lock.

 

In providing the above solution I have now extended the .DominoFramework and provide an example inside the framework of how to impliment persistant document locking.  This involves adding an icon to a view to display an icon next to documents that have been locked.  Clicking on the icon toggles the lock of/on using InViewEdit.  View actions are also provided to support the locking/unlocking of documents.  To prevent persistant temporary locks (the lock you get by default when you attempt to edit an unlocked document) I have wired the onQueryModeChange event to call a method that validates that a persistant lock already exists.  This code will all be abvailable as part of the next beta release of the .Domino Framework.

I have also added to the .Domino Framework Wiki with content about what I have learnt and suggest when working with Notes document locking:-

 

Document Locking allows Notes application to control edit access to a single document by more than one user. The standard Notes Document Locking feature will only work where an Administration Server (aka master lock server) has been nominated in the ACL of the database and the Allow Document Locking property set for the database.

Lock Types

The following are the different lock types that can occur on a document:-

Type Description
Persistent This occurs when the user (or code) places a lock on the document directly.
Persistent Temporary This occurs when the user attempts to edit a document and the master lock server is available and permits the lock. The lock is supposed to be removed when the user finishes editing the document, but this is not always the case.
Provisional This occurs when the user (or code) places a lock on the document directly and the master lock server is not available. The provisional lock may be promoted to a persistent lock when the master lock server becomes available.
Provisional Temporary This occurs when the user attempts to edit a document and the master lock server is not available. The lock is supposed to be removed when the user finishes editing the document, but this may not always be the case.

Fields

The following is a list of fields used in supporting document locking:-

Field Description
$PTWriters Names of the people/groups holding a provisional temporary lock on a document
$PWriters Names of the people/groups holding a provisional lock on a document
$Writers Names of the people/group holding a lock on a document
$WritersDate? Date/time document was locked

Errors

The following are some of the errors associated with document locking:-

Error Description
4000 User is not authorized to lock/unlock the document. This can occur if the user does not have edit authority for the document or they are attempting to unlock a document locked by somebody else without manager access.
4595 Document has been locked by somebody else
4597 Master lock server not available

Best Practices

  • The only reliable way to implement document locking seems to be to support persistent locking only (not persistant temporary locking). This requires that a lock be placed on a document when the master lock server is available. The document can then be safely edited before the lock then released.
  • To prevent a persistent temporary lock being created it is necessary to prevent the document being placed in edit mode when first opened. This is best handled in the PostOpen? event by setting Source.EditMode? = False. It is also necessary to prevent a document being placed in edit mode unless the document already has a persistent lock. This is best handled as part of the QueryModeChange? event.
  • If the form has an Edit action then hide the Edit action if the name in the $Writers field is not the current user.

Notes

  • A person with Manager access can unlock/edit a document locked by somebody else. If you wish to prevent this happening from inside LotusScript code, check the contents of the $Writers field first before invoking the Unlock method.
  • There seem to be a number of scenarios when can result in a temporary lock remaining after the user closes a document or switches from edit mode. These locks must be removed manually or via an agent (lock decay).
  • When edit locking is implemented, it appears that if another person attempts to edit the same document on another server then the updated copy of the document is used even if replication has not yet taken place. I accnot find any documentation on this, but it seems to be a BONUS.
  • If a document is opened in read mode and somebody subsequently edits the document, the original user will receive a warning if they then try to edit the document they have open. They are warned that they should close the document and re-open it (to get an updated copy). If they ignore this warning and try to edit the document a second time no warning is displayed and the old version of the document becomes editable. this will almost always result in a replication conflict and/or an e-mail being generated that warns about the potential loss of data.
  • If locks are placed on a local replica of the database, details about the lock may not replicate to the other servers. In this case the master lock server is still aware of the lock even though the server documents do not contain the $Writers and $WritersDate? fields.

Related Information

.Domino Framework Roadmap

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

For those of you that have found the code contained within the .Domino Framework usefull, the following is a brief roadmap for the project.

 

<