One thing that has struck me about the Notes 8.5 beta is that X-Pages implements JavaScript as the only option for both client-sided and server-sided scripting. Neither @Language nor LotusScript appear to be supported directly but the "JavaScript" language has been expanded to provide @Formula emulation. The new server-sided JavaScript now also seems to be able to do some of the things only done in the past using LotusScript... When X-Pages is made available for the Notes client I am expecting to see support for JavaScript only. We already have LotusScript able to run on the Notes client and Domino servers, so why is IBM going to so much trouble to extended JavaScript for server-sided scripting? Could it be that LotusScript is not part of the long term vision IBM has for Notes development? As a devoted LotusScript programmer (biggot) I am hoping I am wrong...
The next version of Notes (post 8.5) promises to be a very interesting one for Notes developers. Consider a scenario in which:-
- X-Pages provides an alternative to Forms, Views, Pages, and Subforms with the added advantages of running on both a Web client and a Notes client, plus the ability to link to non-Notes data sources;
- X-Pages supports "JavaScript" directly but not LotusScript or @Formula
- There is little or no future extension of LotusScript language to make it a more modern OOP language;
- There are few (if any) enhancement made to "old-style "design elements such as Forms, Views, Pages, Subforms, Framesets, Outlines;
- The Eclipse IDE does not provide native support for these older style design elements - although we do get the LotusScript editor almost everyone has been waiting for.
It sounds to me like a completely new Notes II programming environment has been created. An environment in which many of the Notes development paradigms of the past have been replaced, including either the death (or significant downsizing) of the role of LotusScript. Will we have the choice of staying with what we know (e.g. LotusScript & @Formulas) or will we have to move to a new way of doing things (most likely JavaScript based0)? And where does Java fit with this? Hopefully IBM will soon provide a clearer picture to the public of its plans for Notes development post Notes 8.0.
Perhaps those more in the know than I can comment about where I am completely wrong.... "Whenever you have eliminated the impossible, whatever remains, however improbable, must be true".
|
Does LotusScript Have a Future?
|
The latest beta of the .Domino Framework has been released at OpenNTF. This release inclorporates the new Inspector tool and adds an application template that can be used to build a new application from scratch that includes the generic application components of the .Domino Framework.
Wordle of .Domino Framework

|
.Domino Framework 0.5 Beta Released
|
I am just putting the finishing touches on what I believe will the most useful tool to be provided as part of the .Domino Frramework yet. The tool is called Inspector and the following provides a brief summary of what its capabilities will include in its initial release:-
-
View and change database properties
-
Select another database
-
Perform actions against the database (e.g. Open, Sign)
- View data documents, profile documents, design documents, and deletion stubs
- Build a document collection using any combination of search, FT search, view, or manual selection
- Enter a Notes URL, NoteID, or Document UNID to select a specific document
- Display the documents contained in the document collection.
- Navigate through document collection
- Perform actions against the document collection (e.g Setting field values, removing template inheritance)
- Display details about any one document in collection
- Display a list of items in the document
- Perform actions against the document (e.g. Delete, Sign)
- Display and edit information about any item in a document (type, value, flags)
- For LotusScript Libraries show details of the classes, methods, & properties contained in the design document.
This functionality can invoked from ANY Notes database regardless of whether or not it implements the .Domino Framework. This is done via a Toolbar "Magic Button" that passes information about the current database/document to the .Domino Framework database.
I see a LOT of potential for expanding the tool further to expose even more of the functionality built into the .Domino Framework. E.g. Providing the ability to apply XSLT to transform data and design documents using styles sheets that reside in the .Domino Framework database.
The 0.5 Beta of the .Domino Framework onm OpenNTF is planned for later this week.
|
A new Notes data management tool (Inspector)
|
I have just finished expanding the Domino.Reflection namespace to allow the new Inspector tool to browse the contents of LotusScript libraries.
Inspector will be able to display information about data documents, profile documents, design documents, and deletion stubs found in ANY database. Inspector will be able to provide a list of all (or selected) design documents found in a database (Domino Designer is not required).
As part of the display information for Design documents I have decided to provide information about any classes found in a selected LotusScript library. Using the extended DominoScriptLibrary class (part of the Domino.Reflection namespace), I can now return a list of properties and methods for a nominated class. I can also get the code used for any one of the properties/methods. Combining these features together Inspector becomes (amongst other things) a basic class browser for LotusScript libraries.
Both the extended Domino.Reflection namespace and the new Inspector tool will be released as part of the 0.5 beta of the .Domino Framework planned for the end of this week.
|
Domino.Reflection Namespace Extended
|
NotesURL is a property available for the NotesSession, NotesDatabase, NotesView, NotesForm, NotesAgent, and NotesDocument classes. It was one of those properties I had never really paid much attention to. That was before I found myself needing to pass references to Notes objects from one application to another. It is not the only way to pass references to these objects but it is perhaps one of the simplest to implement and is consistent across each of thes objects.
At the other end, the NotesSession class has a Resolve method. This is basically the reverse of NotesURL, taking the URL and converting it back into an object (it also works with HTTP URLs too!).
So lets take the scenario in which a Services Oriented Architecture (SOA) is being built. One application (Notes database) provides one or more services to other applications. These services could operate against a database, view, document etc. To invoke the service I need to provide a failsafe way to provide details about the database/view/document against which the service operates. I can pass this in a number of ways:-
- Save the NotesURLs as environment variables in the Notes.INI
- Create a document in the other database with the NotesURL(s) placed inside a field
- Invoke a Web service (increases the ability for Non-Notes applications ualso using the service)
The alternatives for a NotesDatabase include servername and filpath, or replicaid. Server/filepath requires two parameters to be provided or an artificial way to combine these together. Replicaids represent a single string but lack the ability to designate a specific server (I may have made a change to a document on one server which has not replicated to other servers and hence the serice may not operate against the latest data if it uses another replica).
Views are more difficult to define as the only other standrad way to access a view in LS is via NotesDatabase.GetView. This requires the name or alias of the view and this is not guaranteed to be unique. Plus I need to make sure the parent database is also known. NotesURL and Resolve gives us a way of ensuring the exxact same view is used within the service.
NotesDocumehts have a DocumentUNID that serves us well, but again we need to provide a reference to the parent database for this to work. The NotesURL gives us all this information in a single string.
Note: It is also possible to serialize a NotesDocumentCollection by passing an array of NotesURLs. This is a litlle messier as more code is needed on the other side to reconstruct the NotesDocumentCollection.
I have used the above in the latest beta of the .Domino Framework to implement the new Inspector tool. This tool will provide a "magic button" to view/edit the attributes of the current database, document collections, and document. The code for all this to work resides in the .Domino Framework template. To get this service to work against any database (regardless of whether it implements the framework or not) I have devised a ToolBar button that will save details about the currenty database, view, document etc. and pass them to the Inspector tool via Notes INI variables. For applicatuions that implement the framework the ablity to pass information about the currently selected documenyts ina view is added without using Notes.INI variables. Because this is a Notes 6.0 framework I have not (yet) developed a Web Service option.
The .Domino Framewokr has also been expanded so that the constructors for the DominoDatabase, DominoView, DominoDocumentCollection, and DominoDocument classes can take a NotesURL as a parameter for the constructor.
Notes: Because the object refered to by a NotesURL can represent any one of the supported Notes classes it is sugessted that it be resolved into variant first. Invalid NotesURLs throw an eror so it is also necessary to set the apporpriate error trapping to handle this.
Example: The following code is the DominoDocument class to locate a document using a key that could represent a NotesURL, HTTP URL, NoteID, or DocumentUNID.
'/** ' * Locates an existing document based upon the document's key ' * @param Key Key that can be used to locate the existing document (NoteID, UNID, Notes URL or HTTP URL) ' */ Sub GetByKey(Key As String) Dim NotesObject As Variant On Error Resume Next ' Prevent error if key is not a a valid NotesURL If Ucase(Left(Key,Len(STRING_NOTES_PROTOCOL_PREFIX))) = STRING_NOTES_PROTOCOL_PREFIX Or _ Ucase(Left(Key,Len(STRING_HTTP_PROTOCOL_PREFIX))) = STRING_HTTP_PROTOCOL_PREFIX Then Set NotesObject = Session.Resolve(Key$) If NotesObject Isa "NotesDocument" Then Set iDocument = NotesObject Exit Sub End If End If Select Case Len(Key) Case 8 ' Possible NoteID in LS format Set iDocument = DB.GetDocumentByID(Key$) Case 9 ' Possible Note ID in @Language format Set iDocument = DB.GetDocumentByID(Left(Key$,8) + Right(Key,8)) Case 32 ' Possible UNID Set iDocument = DB.GetDocumentByUNID(Key$) End Select Exit Sub End Sub
|
NotesURL and Resolve
|
|
Whilst a native eclipse editor is not yet available in Designer 8.5 for Forms and View it seems that option is provided to edit the DXL for these design elements. This provides both raw DXL/XML code and a node/property tree for these design elements. There are times when this can be a distinct advantage over the traditional Domino Designer tool to find and set values (e.g. search and replace". Not all Design elements are supported (e.g. LotusScript Libraries).
|
Editing Design Properties Via DXL In Designer 8.5
|
Let me first start by saying I am not a design partner and I do not have any inside contacts at IBM, so I have absolutely no inside information as to what IBM's plans are for the future of Notes programming. But because I am not subject to any non-disclosure agreements I am free to speculate and say whatever I like. If I start to take a closer look at the tea-leaves now forming at the bottom of my yellow mug I wonder if there may be a pattern forming I had not seen before....
I have been taking a much closer look at X-Pages, the new design element that is part of Notes 8.5. This design element looks nothing like any other existing Notes design element. And not just because of the new Eclipse editor. I see a whole bunch of new controls that remind me more of my time as an ASP.Net developer than they do of Notes development. I see the ability to bind these controls to data sources that include not just Notes documents and Notes views but also to SQL-databases and XML. Again, this is not unlike ASP.Net development (except for the ability to natively link to Notes databases). I also see that as I design an X-Page, it is building XML code which I can not only see but edit directly....
And when you look at the functionality of X-Pages, they seem to be able to do pretty much everything that many of the existing UI elements of Notes (Forms, Subforms, View, and Pages) can do. Except that I can now combine them in ways that were never possible with these other design elements. A number of other bloggers are starting to rave about the really cool stuff they can do using X-Pages.
I believe IBM are on record as saying they intend to make X-Pages available for the Notes client in a later release. So what does that mean? Unless X-Pages for Notes has a different set of controls that mirror more closely the existing set of controls I am probably going to be soon building new applications for the Notes client in a completely new way. And thanks to X-pages these applications will look and behave the same on a Web client.. If X-Pages provides the functionality of other design elements such as forms why would I use both in an application? Perhaps I am not supposed to? Perhaps in a post Notes 8.5 world I am now supposed to do most of my UI design using ONLY these new design elements such as X-Pages?
Perhaps round-tripping of DXL is not an issue for IBM because they see a future for us developers where we will be able to edit the XML from inside Notes. Perthaps IBM are not making a major push to develop Eclipse editors for Forms, Pages, and Views because they see these design elements going the way of the Navigator (i.e. no new features added in future releases). Perhaps there is no need to extend other Notes design elements such as views to support style sheets for the same reason.
It is not immediately clear If LotusScript will form a key component of the brave new world. I am hoping so, because one of the reasons I believe the world has as many Notes applications as it does is that non-programmers (and many programmers) are often better able to teach themselves to program in BASIC-based programming languages much more so than they have ever been able to with Java, C, or JavaScript like languages...
The tea-leaves are still swirling around and so the future may show that I am completely wrong. (But I do hope the dead fly floating at the top is Sharepoint!). But just in case I am not completely wrong , I would suggest Notes Developers take a very close look at X-Pages - even if you do not do a lot of Web development. X-Pages (and custom controls) just might provide an insight into how you will be building Notes client and dual client applications in the years to come. Oh... and read the blogs of those that are design partners. They may not be able to say a lot just yet... but look at what they don't say!
|
Is Notes Programming As We Know It About To Change...
|
Defensive programming involves writing code in such a way as to handle unforseen circumctances. Too often when I look at code that is developed for Notes applications I see little or no evidence of defensive programming being used.
Notes applications more than any other of the major development platforms cries out for defensive programming. Unlike SQL-based databases, Notes databases do not have a data schema and hence do not require that every document (row) contain the same finite list of fields (columns). Nor does Notes require that each field (column) be of the same data type. Notes fields also do not restrict if it can represent a single value or a list. So there is always the real risk that the data may not contain what you expect.
As an example, lets look at an employee record which has an EmployeeNo field.
The following LotusScript code could result in an error for for many reasons:-
EmpNo = Doc.EmployeeNo(0)
- The variable Doc may not yet be instantiated (i.e. be connected to an existing Notes document)
- The field EmployeeNo may not exist in the current document
- The value inside the EmployeeNo may not be of the same type as the variable EmpNo. (it is not even clear from the code whether EmpNo is text or a number.
- Unlikely, but should EmployeeNo ever become a method or a property of the NotesDocument class then the code would no longer work.
The following alternative code protects us from many of the above potential problems.
If Not Doc Is Nothing Then
If Doc.HasItem("EmployeeNo" ) Then
EmpNo$ = CStr(Doc.GetItemValue("EmployeeNo" )(0))
End If
End If
- We are making sure that we have a Notes document
- We are making sure the document has an EmployeeNo field
- We have made it clear in the code that we are expecting a string (The $ in EmpNo$ causes LotusScript to make sure EmpNo has been declared as a String)
- We are making a reasonable (but not complete) effort to convert any non-text values to a text value (assuming the values should be text). i.e. This works for numbers or dates but would fail for a Rich Text field.
This of course results in a lot of extra code being required each and every time you attempt to access the contents of a Notes field. Which probably expains why people often don't bother!!!
Another approach that can result in a reduction in the amount of code required and making the code easier to follow is to adopt Object Oriemted Programming techniques to make EmployeeNo a property of an Employee Class
Class Employee
Property Get EmployeeNo$ As String
If iDocument Is nothing Then Exit Property
If iDocument.HasItem("EmployeeNo$) Then EmployeeNo$ = Cstr(iDocument.GetItemValue("EmployeeNo" )(0))
End Property
End Class
Now each time I need to access the EmployeeNo field in my application I can write the code as
EmpNo$ = Employee.EmployeeNo$ or If Employee.EmployeeNo$ <> "" Then
You will notice within the .Domino Framework that this technique is used repeatedly, especially when using the DominoDOcument class and extensions of that class. The .DominoFramework also provides a property generator tool that automatically generates the LotusScript code for a property based upon the property name, notes field name, and the intended data type. This takes a lot of the hack work out of creating all the property definitions needed when creating a new class.
Note: The above is but one of many defensive proramming techniques that could be employed. In many cases it comes down to personal preference, coding style and/or coding standards.
|
Defensive Programming
|
|
When calculating milestones based upon a starting date it can often be necessary to treat the "last day of the month" a little different to other dates. That is, if the base date is 28 Feb 2007, then "next month" is usually held to be March 31 2007 and "next year" is usually held to be 29 Feb 2008. Whereas if the base date is 27 Feb 2007 then "next month" is usally held to be 27 March 2007, and "next year" is held to be 27 February 2008. This result can be achived by always adding one day to the starting date, incrementing it by the required amount and then subtracting 1 day. When a starting date is the last day of the month,adding 1 day moves the date to the 1st of the next month. After adjusting the date subtracting 1 day will move dates still on the first of a month back to the last day of the previous month. This not only accounts for differences in the number of days in each month but also those pesky leap years.
|
Retaining Month End Dates
|
When developing the .Domino Framework I always had problems distinguishing the relationship between the DominoDocument (NotesDocument) and DominoUIDocument (NotesUIDocument) classes. It didnt seem like the DominoUIDocument class should have many properties or methods as these should typically be part of the DominoDocument class. Typically an extension of the DominoUIDocument class would only have event handlers. Regardless of whether I accessed a document via the foreground or background I really needed to have the same set of rules applied to the object. E.g. The same validation/transformation/logging needs to be applied to the property of an object when it is edited on a form, edited via in-view editing, and/or assigned a value in an agent.
So after giving this a lot of thought I have decided to remove the DominoUIClass as part of the next release. The DominoDocument class will now extend both the NotesDOcument and NotesUIDocument classes. By passing a NotuesUIDocument to the constructor of the DominoDocument class the framework is able to establish that the document is being accessed in the foregorund and make available those additional features that only apply when editing a document via a form. I feel confident this will lead to a cleaner, simpler solution for working with Notes documents in an object oriented way.
Note: One of the reasons the .Domino Framework is still in beta is so that I can do this (remove/rename classes and/or change the footprint of methods/properties).
|
DominoUIDocument Class Goes
|
Having undertaken a review of the Notes 8.5 public beta I have decided that I will not be developing a version of the .domino framework for the 8.5 release. My current plans were (and still are) to release 1.0 of the .Domino Framework later this year that is fully supported with Notes 6.0+. After this initial release I had planned to then jump to Notes 8.5 and start developing functionality specific to this release.
I find Notes 8.5 to be a major disappointment for Notes client development and see no compelling reason to develop a version of the .Domino Framework for this release. For one thing there is little or no new features in this release specific to Notes Client functionality. The design elements such as X-Pages and Custom controls are supported on the Web client only. Then there is the new eclipse IDE which does a great job for these new design elements but leaves all the existing design elements worse off than before. (And don't get me started about the absence of an eclipse editor for LotusScript!!!). So until IBM starts to get fair dinkum with providing something new for Notes client development All post 1.0 releases of the .Domino Framework will be developed for the Notes 8.0 stream. This includes support for composite applications - something I am quite excited about. I suspect a lot of people will bypass this release of Notes anyway and wait for the REAL 8.5 release to become available.
|
Notes 8.5 Will Not Be Supported
|
DominoDocumentCollection.Sort - verb - origins unknown - Geek speak for sorting a collection of documents...
Sorting algorithms are typically implemented to only sort scalar values (text, numbers, dates). The .Domino Framework implements a combination of the QuickSort and SelectionSort algorithms as part of a generic atfSort function included within the Domino.@Functions namespace. The next beta release of the .Domino Framework will contain an enhancement to this function to sort vectors. Vectors are a way of storing complex data structures by separating them into two components (1) The object itself and (2) a key value. The .Domino Framework implements vectors via a simple DominoVector class which is found in the base Domino namespace.
The sorting of document collections therefore becomes one of creating a collection (array) of vectors in which the value is a NotesDocument and the key is whatever value is desired to sort the collection (e.g. UNID, date last modified, or the value of a specific field). Following my posting yesterday on the DominoDocumentCollection class Nathan Freeman provided some cool code for sorting a document collection based upon a specific view. Thanks to Nathan's contribution I have now been able to extend the functionality of the new Sort method to allow the documents to be sorted in the same order they appear in a designated view.
The 0.5 beta release (which includes this new method) is expected to be published on the 29th of June .
|
DominoDocumentCollection.Sort
|
For those of you have have asked the question "How do I use the .Domino Framework in my applications?"... The simplest approach is as follows:-
1) Copy the following LotusScript Libraries from the template to your application:-
base.Domino
base.Domino.Applications
base.Domino.Errors
base.Domino.@Functions
Domino
Domino.Applications
Domino.Errors.OpenLog
2) Create a new LotusScript Library Domino.Applications.applicationname and include the statement Use "Domino.Applications".
3) Create new classses within this LotusScript library that extend the classes found in Domino.Applications (e.g. DominoDocument). These classes add proprerties/methods that are specific to your application.
Note: You can exclude Domino and Domino.Applications libraries, but your application will now be extending classes such as baseDominoDatabase, baseDominoDocument instead of DominoDatabase, DominoDocument and the include becomes Use 'base.Domino.Applications"
The above provides the core Business Logic Layer of the .Domino framework implemented via LotusScript. Presentation Layer components and advanced business logic components require additional design elements to be copied from the template. The template does document the design elements used by specific components.
|
Tip: A Simple Implementation of .Domino Framework
|
The next beta release of the .Domino Framework will contain a significant extension of the DominoDocumentCollection class.
Unlike the NotesDocumentCollection class, it DOES have a constructor making it possible to gather a wide range of document collections, including an EMPTY document collection.
The NotesDocumentCollection extended by this class depends on the type of parameter passed to the constructor:-
- Nothing: Creates an empty document collection for the current database
- NotesDocumentCollection: Extends a NotesDocumentCollection you provide
- NotesDatabase: Collection with all documents in the database
- NotesSession: The list of documents an agent or view action is set to run against
- NotesNoteCollection: A collection of the design notes
- NotesViewEntryCollection: Converts the view entry collection to a document collection
- NotesDocument: Creates a document collection with a single document
- NotesView: Creates a document collection with all documents in the view
- ENUM_COLLECTION_TYPE_CONFLICTS (Constant): Collection of all conflict documents in current database
- ENUM_COLLECTION_TYPE_LOCKED (Constant): Collection of all locked documents in current database
- ENUM_COLLECTION_TYPE_READERS (Constant): Collection of all documents in current database with reader fields
- ENUM_COLLECTION_TYPE_AUTHORS (Constant): Collection of all documents in current database with author fields
- String Array: Builds a document collection assuming the elements in the array represent any combination of Note IDs, Document UNIDs, Notes URLs, and/or HTTP URLS.
The class will also contain an AddDocuments method. Similar to the NotesDocumentCollection.AddDocument method, this will provide the ability to add multiple documents to the document collection, including most of the options provided in the constructor.
|
DominoDocumentCollection Class
|
The 0.5 Beta release of the .Domino Framework will contain an application template. This is another one of the many missing pieces of the framework that I wish to complete before the framework is ready for a 1.0 release. The .Domino Framework contains so many pieces that it is often difficult to establish which components should be included when building an application based upon the .Domino Framwork. The new template will contain all the components that can be used in building a Notes application. Notes developers can then delete the components that are not required for an application (e.g. exporting to Excel, importing holidays, managing keywords etc.). I am also working on the documentation contained in the templates and the wiki to help developers better understand how to create applications using the .Domono Framework as a component library as well as how to extend the framework within each application.
Note: Every Notes application I now build is based upon the .Domino Framework and it is halving the time it takes me to build these applications.
|
Application Template
|