Ben Langhinrichs

Photograph of Ben Langhinrichs

IBM Champion logo

E-mail address - Ben Langhinrichs






August, 2003
SMTWTFS
     01 02
03 04 05 06 07 08 09
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

Search the weblog





























Genii Weblog


Civility in critiquing the ideas of others is no vice. Rudeness in defending your own ideas is no virtue.


Sat 2 Aug 2003, 09:57 PM
I was reading Joe Litton's post entitled Notes/Domino developers: it IS time to learn Java, and I thought maybe it ws time to re-introduce the concept of Midas for Java.  I have raised this flag in the past, as many as four years ago, but nobody saluted then.  Now is your chance again.  Would you like to see a Midas for Java, basically as a fully compatible Java version of the Midas Rich Text LSX?  Same chunk definitions, same flexibility, almost identical naming (you would need get/set pairs for "properties", and that sort of thing)?  It wouldn't even be that difficult, except for the QA and inevitable documentation issues, but I'd want to see some interest before going forward.  Speak up now, or don't complain later that we weren't listening!

Copyright © 2003 Genii Software Ltd.

Sat 2 Aug 2003, 12:17 PM
For those who have not used our Midas Rich Text LSX much, or have used it primarily from samples such as the Send It! sample, you might want to start by reading the first article in this series, Midas 101 - Chunk Definitions.  Even for those familiar with chunk definitions, the current topic may come as a bit of a surprise.
  
To recap a bit, the Midas engine relies on a peculiar design methodology.  The Notes Object Model, which basically maps a class to each discrete entity, such as a document, a view, a database, an item, etc.  The Midas Object Model has very few classes, and primarily relies on a single class, the GeniiRTChunk class.  This "chunk" represents a portion of the rich text in somewhat the way a view represents a portion of the document collection of a database.  

In a view, there are selection criteria which determine which portion of the document collection to show.  Within that selection, there is an order based on sorting.  In the Midas Rich Text LSX, there is a chunk definition, which also determines which portion of the rich text to use.  This may be a single element definition, such as "Button 2", or it my be a group of elements defined by a wildcard or range, such as "Section 2-5" or "Table *", or it may even be a portion of rich text bounded by one or more elements, such as "After Graphic 3".  Finally, the portion of rich text can be narrowed down by drilling down in the definition, such as "Table *; Row 1", which is the first row of every table, or "Inside Section 3; Table 1; Row 1; Column 2-4", which is columns 2 through 4 of the first row of the first table inside the third section.  Phew!

So far, anybody who has looked at chunk definitions in Midas before should be fairly comfortable.  This definition language is powerful and used to great effect, since it allows you to describe a very specific part of the rich text and act on it.  But the part that is often confusing is what happens after you act on it.  This is due to the late binding nature of chunk definitions.

Late binding, by the way, usually refers in programming languages to type definitions.  An early binding is when the type definitions can be checked at compile time.  Late binding is when the type cannot be determined or checked until runtime, which makes error checking more difficult.  The tradeoff is that late binding allows more flexibility, and that is the same tradeoff with the Midas chunk definition.

Consider a rich text field with a number of paragraphs of information including, scattered among the paragraphs, three graphics.  If you wanted to use Midas to access each of these graphics and set its HTML name value, you would have code such as the following:

Set rtchunk = rtitem.DefineChunk("Graphic 1")
While rtchunk.Exists
  Call rtchunk.SetTargetProperties("Graphic", "GraphicHTMLName=G" & Cstr(rtchunk.TargetNth))
  rtchunk.GetNextTarget
Wend

The rtchunk.GetNextTarget call changes the definition from "Graphic 1" to "Graphic 2" and so on, so you cycle through the graphics in the rich text field.  So far, so good.  Now, what if instead of changing the property, you wanted to export the graphics and remove them.  You might modify the above code to look like this:

Set rtchunk = rtitem.DefineChunk("Graphic 1")
While rtchunk.Exists
  Call rtchunk.ExportGraphic("c:\temp\G" & Cstr(rtchunk.TargetNth) & ".gif")
  Call rtchunk.Remove
  rtchunk.GetNextTarget
Wend

The code looks good, but it skips every other graphic, leaving them in the rich text field and not exporting them.  This is an easy mistake if you look at the chunk definitions as describing the original rich text.  After all, you first export and remove Graphic 1, then you export and remove Graphic 2, then you export and remove Graphic 3.  Right?

Well, not exactly.  Let's look at the rich text after each step.  First, you define a chunk called "Graphic 1".  It points to the first graphic in the rich text field.  Next, you export and remove that graphic.  What does the chunk point to?  Does it point to nothing, the way it would if you removed a NotesDocument object?  No.  It points to "the first graphic in the rich text field", just like before.  Except that now, since the graphic that was there before has been removed, it points to what was the second graphic, but is now the first graphic.  Therefore, the code should be more like:

Set rtchunk = rtitem.DefineChunk("Graphic 1")
While rtchunk.Exists
  Call rtchunk.ExportGraphic("c:\temp\G" & Cstr(rtchunk.TargetNth) & ".gif")
  Call rtchunk.Remove
'  rtchunk.GetNextTarget
Wend

This is late binding.  You define a chunk and it is evaluated just as you call the method or check the property.  If you call three methods against the same chunk, you may not be effecting the same rich text.  Remember earlier when I mentioned the similarity to a view?  If you remove a document, it is roughly the equivalent of doing the following:

Set view = db.GetView("Main")
Set doc = view.GetFirstDocument
doc.Remove
view.Refresh
Set doc = view.GetFirstDocument

Because the NotesDocument class has early binding, you have to refresh the view and get the first document again, but the "first" document in the view changes over time.  With the chunk definition, the idea of "first" or any other relative definition changes all the time without a refresh or a redefinition of the chunk.  The chunk is a definition, and the methods and properties act on the rich text through the definition, not on any specific rich text.

Copyright © 2003 Genii Software Ltd.