Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Entries

photo

Fun with ... garbage...

Blog:  Jan Schulz
Jan Schulz
Updated 
No Ratings 0     No Comments 0
photo

DominoDatabase.HasRo...

Blog:  .Domino Frame...
Peter Presnell
Updated 
No Ratings 0     No Comments 0
photo

classy

Blog:  Yellow is the...
Tim Tripcony
Updated 
No Ratings 0     Comments 6
photo

@GetFile & @GetFileC...

Blog:  .Domino Frame...
Peter Presnell
Updated 
No Ratings 0     No Comments 0
photo

DominoDocument.XML

Blog:  .Domino Frame...
Peter Presnell
Updated 
No Ratings 0     No Comments 0

Dogear Bookmarks

.Domino Framework

Blog Authors:  Peter Presnell  

Previous |  Main  | Next

Building "Composite" Applications In Notes 6

Peter Presnell  |     |  Tags:  .dominoframework compositeapplications events oop  |  Comments (3)

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 TripconyJan 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.

Comments

1 Nathan T Freeman      Permalink For the record, the unicache can get very difficult to work with. I did have some measure of success from embedded objects by doing callbacks from the embedded context. If you go back up to NotesUIWorkspace.currentDocument, you can trigger events on that container, and you get a sharing opportunity. I would typically use the Query/Post send events for that.

Did you get my email yesterday?

2 Tim Tripcony      Permalink I just updated my "in-memory placeholders" example from last July... noticed that it wasn't the latest incarnation of my experiments binding to embedded contexts, so I uploaded the newest version:

http://www.timtripcony.com/blog.nsf/downloads/TTRY75G8CT.htm/$FILE/placeholders.zip

The example database just launches to a view inside a frameset, and the view establishes a unicache. All document opens are redirected in a way that allows the document to share a pointer to the unicache with the view. The form embeds a view that also grabs a pointer to the same unicache, and any document opened from the embedded view gets a pointer as well. So anything that impacts objects stored in the cache is accessible immediately from any other open context.

For example, if you open the view and click "List Placeholders", it tells you that you haven't added any yet. But if you open a document, then open another from the embedded view, then open another - either from the view embedded in the last document you opened, or by tabbing back to the original view and opening a different document - then click "Add to Placeholders", then you can switch back to any tab you still have open and click "List Placeholders" again, and it shows the document you just added. This isn't writing anything to disk - it's not updating the user's INI, stamping a profile document, etc. - this is all occurring in RAM.

So in a listener context, you could add some object to the unicache that has a method that responds to notifications from any context. Say, for example, you have one document open in one frame, and a related document open in another frame. When something occurs in the first frame that affects the other, you call the shared object's method, which has a handle on the related UI document and can refresh it, change field values, etc. Pretty powerful stuff... but, as Nathan mentions, this can be tricky to manipulate. Let me know if you have any questions about this - particularly the timing involved in linking everything together, which turns out to be the most difficult aspect of this approach.

3 Peter Presnell      Permalink Thanks for the tips guys, I really appreciate it. It turns out that I was relying on the LotusScript debugger to tell me what events are firing and when. For some reason the events for an embedded view dont get trapped in the LotusScript debugger. By placing teh following line in the PostOpen event I have been able to get a handle on the embedded view.

If Typename(UIW.CurrentDocument) = "NOTESUIDOCUMENT" Then Call UIW.CurrentDocument.Send

I then just need to create a Listener object to respond to that event.

@Nathan: No I didn't receive your e-mail.


Previous |  Main  | Next
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.