I am presently working on a project that requires coordination between separate components contained within a frameset. In Notes 8 this would be considered a composite application but I need to implement this solution in Notes 6.0. Fortuantely there has been some excellent articles recently posted by Tim Tripcony, Jan Shulz , and Nathan T Freeman on the subject of remote event binding - an important part for creating composite applications.
I have now extended the .Domino Framework by adding a new DominoListener class. This class is designed to listen for events that occur in a nominated Notes UI class.
Class DominoListener As DominoBaseClass
Private iParent As Variant ' The object requesting a listener
Private iTarget As Variant ' The UI object being monitored for one or more events
Sub New(Parent As Variant,Target As Variant), DominoBaseClass(ENUM_CLASS__ABSTRACT + "DOMINOLISTENER")
End Sub
Property Get Parent As Variant
Set Parent = iParent
End Property
Property Set Parent As Variant
Set iParent = Parent
End Property
Property Get Target As Variant
Set Target = iTarget
End Property
Property Set Target As Variant
Set iTarget = Target
End Property
End Class
The DominoLIstener class is extended by DominoDocumentListener and DominoViewListener classes designed to specifically listen for events in NotesUIDocument and NotuesUIView classes. ( a DominoDatabaseListener may be added later).
Class DominoViewListener As DominoListener
Sub New(Parent As Variant,Target As Variant)
Call DominoBaseClass..ValidateClass(ENUM_CLASS__ABSTRACT,"DOMINOVIEWLISTENER")
If (Not Typename(Target) = "NOTESUIVIEW") Then End
Set iTarget = Target
End Sub
End Class
Class DominoDocumentListener As DominoListener
Sub New(Parent As Variant,Target As Variant)
If (Not Typename(Target) = "NOTESUIDOCUMENT") Then End
Set iTarget = Target
End Sub
End Class
The above classes are all abstract classes and demonstrate the use of a DominoBaseClass covered in a previous blog to implement/enforce class abstraction.
To wire two objects together I need to create a Listener class that defines the events to be monitored and the action to take when the event occurs. The following demonstrates a single event, but I could just as easily monitor multiple events by adding additional delegates/methods to the code.
Class OpenFeatureListener As DominoDocumentListener
Sub New(Parent As Variant,Target As Variant)
If Not Parent Isa "DominoFeature" Then End
Set iParent = Parent
On Event PostOpen From Target Call DelegatePostOpen
End Sub
Sub DelegatePostOpen(Source As NotesUIDocument)
Dim DesignListUIDoc As NotesUIDocument
Dim DesignListDoc As NotesDocument
Dim DesignList As DominoDesignList
Set DesignListDoc = New NotesDocument(Source.Document.ParentDatabase)
Call UIW.SetTargetFrame(ENUM_FRAME_DESIGN_LIST)
Set DesignListUIDoc = UIW.ComposeDocument("","",ENUM_FORM_DESIGN_LIST)
Set DesignList = New DominoDesignList(DesignListUIDoc)
DesignList.Title$ = iParent.Title$
Call DesignListUIDoc.Refresh()
End Sub
End Class
The listener is invoked in the parent object with a simple statement
Set Handler = New OpenFeatureListener(Me,Source)
Within a composite application an object may have the need to observe multiple objects. I have therefore created a DominoBroker class as a container for Listeners.
Class DominoBroker
Private iListeners As Variant
Sub Register(Listener As Variant)
If Not Listener Isa "DominoListener" Then End
If Not Isarray(iListeners) Then Redim iListeners(0) Else Redim Preserve iListeners(Ubound(iListeners)+1)
Set iListeners(Ubound(iListeners)) = Listener
End Sub
End Class
This is not unlike Nathan's totally cool concept of a unicache. Ideally I would like to have a single Broker for an entire Notes session, but presently I seem to be constrained by LotusScript to only being able to get a handle on UI objects that are currently active (one NotesUIDocument, one NotesUIView) or when LotusScript code launches a UI object (e.g. UIW.EditDocument). So far I have only been able to share the love (broker) around between UI objects that have been loaded by a common UI object (class). Documents opened in preview mode from a view, embedded views etc. are a Remote event black hole.
Combining the above with framesets (to contruct the presentation layer) allows me to implement design patterns in Notes 6 very similar to Notes 8 composite applications. The down side(?) is that I am restricted to only wiring Notes components and only for some very specific scenarios. On the plus side this is all Notes code with no Eclipse required.
Note: The above is designed for Notes 6/7 only. Notes 8 provides additional classes to support composite applications as well as a composite application editor.