I find new experiences are often the greatest source for innovation in my work. This proved to be the case for me several years ago when I left my role as a Lotus Notes Developer to take on a role that involved using C# and ASP.Net. When I returned to Notes development I found myself wanting to take many of the great things I had experienced with .Net development and apply them to Notes development. This gave rise to me becoming an Object Oriented Programmer and also lead to me developing the .Domino Framework. Version 1.0 of the .Domino Framework (available on openNTF) was my way of of taking many of the cool things I had found in the .Net framework, combining them with what I was now seeing with Notes 8.0, and delivering them using the Notes 6.0 technology I was being asked to use in my work. . I am now working on .Domino Framework 2.0. This new framework will be built from the ground up to overcome some of the complexities and limitations found in the original framework. The inspiration for this new framework is coming from the time I spent late last year using Notes 8.5, XPages, and JavaScript (including SSJS) and what I saw at Lotusphere with Project Vulcan. Is there a need for such a framework? Well I believe so. So far this year my own projects have been almost exclusively Classic Notes. Unlike the world of many business partners, there is simply no demand at this time for me to develop XPage applications. Also.... I also only have one month left on one of my current contract so I have been paying much closer attention to the Notes Job market. What I have found interesting is that there is no signs of any significant demand (if any) for Notes developers with XPages experience. It seems to me that the same skills of Notes Classic, LotusScript, LEI etc are the skills being sought for most of the current positions. So after escaping the hype of #ls10 I am beginning to suspect that a very high proportion of Notes development in my part of the world will continue to be done using LotusScript. My first goal for 2010 is therefore to find ways to add the power of JavaScript to the LotusScript language. (And maybe even explore ways in which some of the concepts demonstrated for Project Vulcan can be implemented using Notes Classic.) IBM stopped investing in LotusScript after Notes 6, but that doesn't mean the language should/need die. It never ceases to amaze me just how flexible LotusScript and Notes Classic are as a development environment. . As an example. LotusScript does not provide an extensive set of operations that can be performed on arrays. So I have developed a new DominoArray class as part of the core of the .Domino Framework 2.0. This class add properties and methods that are found in @Formulae, JavaScript, and Java that were never added to LotusScript. Being a class it is now also possible to exhibit some of the capabilities and styles JavaScript provides with its own data types being implemented as customizable Objects. The DominoArray class provides a length property (as provided in JavaScript and @Elements). A number of methods have been implemented such as push(), pop(), slice(), splice(), reverse(), toString(), sort(), contains() (@Contains), keword (@Keywords), and subset (@Subset). Using the DominoFramework 2.0 it becomes possible to write code that looks remarkably like some of the JavaScript code I had started to write last year. e.g.
Another example is the Math object that is provided by JavaScript. To reproduce this in LotusScript I have defined a DominoMath class as a container for all those special mathematical operations and constants not built into LotusScript. By defining a global variable Math, which instantiate an instance of DominoMath, it becomes possible to write LotusScript code that looks very much like JavaScript. e.g.
If there was one message I could leave for the still many Lotus Notes developers not yet doing projects with XPages, Vulcan etc.... It doesn't matter if you are still using Lotus Notes R5 or that Notes 8.5.1+ may still be several years away. Nor does it matter if you have little or no access to Lotus products such as Connections, Quickr, or LotusLive. Try and at least take a close look at what all these products offer. And then go back to your own environment and think about how you can implement some of the cool features these other products provide. With any version of Lotus Notes from R5 onwards you have the most powerful, flexible, and adaptive product in the Lotus family. All that is required is a little inspiration and some cool LotusScript code. (or of course you could wait for the .Domino Framework 2.0 to become available).
As I slowly work my way through XPages school I am collecting all my written assignments and placing them in a project folder. This project folder is known on OpenNTF as the xDominoFramework project. The project can be downloaded from OpenNTF or you can view various aspects of it on-line from www.dominoframework.com. : Some of the material was written using crayons while I was in XPages kindergarten. Some material is a little better having been written during my time in first grade. It still has a long way to go but it may offer some assistance to those making a similar journey. You can expect it to improve over time as I learn more about XPages and SSJS. The content is built from the .DominoFramework and adds the following:- Developer Tools: New Summary - I have added a new summary of the developer tools using Xpages repeater control as an alternate way to style a view. Event Simulator - Following on fromk my recent blog I have provided an on-line event simulator to explore the order tghat evnts are executed on an Xpage. Code Generator - This tool has been extended to produce property code for SSJS. Application Design The Web version demonstrates how a dijit tree control can be combined with framesets to allow an outline control to be generated as Xpage components. Themes & Styling I have started to collect a series of popular style sheets such as bluprint, bluetrip, and OneUI (inlcuing the OneUIDummy developed by Stephan Wissel). OOP Framework The first attempts have been made at creating a library of SSJS that mirrors the LotusScript Domino class that formed the nucleus of the .Domino Framework. Yellowverse I have added an updated version of my blog - Devil's Guide to the Yellowverse as well as provided links tgo wide range of community resources of use to the Note community. Please feel free to provide any feedback on this project either here or via the .Domino Framework bleedyellow community
One of the (many) cool things about Notes is that the code exists in the NSF as documents much the same as data documents. This means we can do many of the same things with design elements as we do documents. And that includes tagging. I have been doing some work over the weekend to take some of the stuff I am developing for Discussion NextGen and adding it to the .Domino Framework to allow users of the framework to easily discussion-enable any application. To assist in this process I need a simple way to identify the design elements that are needed to discussion-enable an application. Users of TeamStudio Design Manager may know that the product provides a way to easily update a group of design elements from one database into another. This is done by "tagging" design elements with group names. Underneath the hood this works by storing the groups (tags) in a field called $GroupInfo. Not wanting to reinvent the wheel I have been making use of this field within the .Domino Framework. e.g. I have a view that will display all design elements categorized by $GroupInfo. Today I added an new view action that allows you to assign new tags to the $GroupInfo field. This essentially provides you with a way of assigning tags to design elements and view the design elements grouped by tag. And if you use TeamStudion Design Manager you get the added benefit of being able to move all the design elements with a specific tag between databases. Keep a look out for the next version of the .Domino Framework for this and other developer tools. The next version is being developed for Notes 8.5.1 and will include tools and code for XPage and SSJS developers.
As part of my work on the Discussion NextGen project I have been looking at ways the discussion thread capabilities provided by a discussion database could be easily added to any existing Notes Application. I have now taken the work I have done so far on Discussion NextGen and folded it back into my own.Domino Framework project. With a few tweaks I have been able to
Add a discussion area to the framework database in which people can add new discussion topics and/or create responses; and
Add discussion threads tied to other documents that already existed in the framework database.
The steps involved to discussion-enable your own application would include:-
Copy a defined collection of design elements into your application
Add outline entries that connect to the standard Discussion views you wish to include
Add a sub-form to any existing forms you wish to discussion enable
There will also be some advanced configuration options available with the installed code that can be added
that would allow you to fine tune the discussion capabilities you
require. e.g. Turning off advanced discussion features such as sticky
Notes, read-only topics etc. My goal is to make this task no longer than 5-minutes and in the coming weeks I hope to have a 5 minute video that proves it. Note: It has not yet been determined if any of these feature will be included as part of IBM's discussion template. But at the very least you can expect the components to be available as part of an upcoming release of the .Domino Framework.
As many of you many know I have been lucky enough to have the chance to participate in the OpenNTF project to extend the Discussion template. The team includes Niklas Heidloff and Steve Castledine, two of IBM's great application developers. These guys are constantly coming up with great ideas for this project. One of Niklas's contributions was the idea of using video as a medium to communicate some of the ideas we have for the template. Thanks to Niklas it is now occurring to me that video may be one of the missing pieces for one of my other OpenNTF projects, the .Domino Framework. Here is my first video which explains one of the framework's developer tools, the Property Generator and how it can be used in conjunction with the new Eclipse LotusScript Editor to quikcly generate LotusScript classes. So if you haven't yet had a chance to see the new LotusScript editor up close, here's your chance.
Release 1.0.2 of the .Domino Framework will contain the first small steps for building an SOA. The existing Connections feature (available with 1.0) will be extended to support Web Services. For those not familiar, the concept of Connections is to define all external dependencies an application may have via a series of "Connection" documents. This eliminates the need for hard-coding the information about external resources. As documents these can be changed without the need for code changes. As data documents these can be copied from application to application. Even the basis for the connection can be changed (e.g. a connection to a Notes database can be defined using servername/filpath, replicid, or NotesURL and then changed on the fly to one of the other methods). The same need exists when linking to Web services. The URL used to invoke a Web service will also change each time there is a change to the server name, or filepath. This includes when an application migrates from a development environment to qa and on to production. By creating a Connection document for each web service we can change details about the web services withou the need for coding. The following is a sample of the standard code from a Web Service Consumer generated by importing a WSDL:-
%INCLUDE"lsxsd.lss" Class PropertyGenerator As PortTypeBase SubNEW Call Service.Initialize("UrnDefaultNamespacePropertyGeneratorService",_ "PropertyGeneratorService.Domino", "http://devservername.domain.com:80/dominoframework2.nsf/PropertyGenerator.wsp?OpenWebService",_ "PropertyGenerator") EndSub Function GENERATEPROPERTY(LANGUAGE AsString, PROPERTYNAME AsString, FIELDNAME AsString,_ FIELDTYPE AsString, GETREQUIRED AsBoolean, SETREQUIRED AsBoolean, TRACKCHANGES AsBoolean)AsString Let GENERATEPROPERTY = Service.Invoke("GENERATEPROPERTY", LANGUAGE, PROPERTYNAME, FIELDNAME, FIELDTYPE, GETREQUIRED, SETREQUIRED, TRACKCHANGES) EndFunction EndClass
As you can see, the server name and filepath of the web service is hard-coded. If this pointed to a dev server you would need to change the code before it is migrated to production (never a good idea). Using a Connection the code could be rewritten as
%INCLUDE"lsxsd.lss" Class PropertyGenerator As PortTypeBase SubNEW Dim URL AsString URL$= GetConnectionString("PropertyGenerator") Call Service.Initialize("UrnDefaultNamespacePropertyGeneratorService",_ "PropertyGeneratorService.Domino",URL$+"?OpenWebService","PropertyGenerator") EndSub Function GENERATEPROPERTY(LANGUAGE AsString, PROPERTYNAME AsString, FIELDNAME AsString,_ FIELDTYPE AsString, GETREQUIRED AsBoolean, SETREQUIRED AsBoolean, TRACKCHANGES AsBoolean)AsString Let GENERATEPROPERTY = Service.Invoke("GENERATEPROPERTY", LANGUAGE, PROPERTYNAME, FIELDNAME, FIELDTYPE, GETREQUIRED, SETREQUIRED, TRACKCHANGES) EndFunction EndClass
A little over a year ago Nathan Freeman published an article about Universally Unique Identifiers (UUIDs). The article also refers to work being done by other Notes developers on exploring ways in which Notes applications can speed up the process for locating documents. The technique involves using the @Password function to create a random UNID for a document based upon some external key you have for the document. This subject came up again in a conversation I was having over the weekend with Nathan and Tim Tricony. The result of the conversation is a new GetDocumentByUUID method that I am adding to the DominoDatabase class for .Domino Framework 1.0.2. The code below can be adapted as a way of generating a UUID for a document.
'/** ' * Return a document based upon the UNID being composed of the hasked value of the key ' * ' * @param Source The external key for the document ' * @param Create True = return new document if no existing document found, False = only return an existing document ' * @return A document with the matching key ' */ Function GetDocumentByUUID(Source AsString,Create AsBoolean)AsNotesDocument Dim ReturnValue AsVariant Dim UNID AsString Try: OnErrorGoto Catch OnError 4091 ResumeNext' Document does not exist with UNID ReturnValue =Evaluate(|@Password("|+Source$+|" )|) UNID$=Mid$(Cstr(ReturnValue(0)),2,32) Set GetDocumentByUUID = iDB.GetDocumentByUNID(UNID$) If(Not GetDocumentBYUUID IsNothing)ThenExitFunction If(Not Create)ThenExitFunction Set GetDocumentByUUID =NewNotesDocument(iDB) GetDocumentByUUID.UniversalID$=UNID$ ExitFunction Catch: Stop ReportError Nothing ExitFunction EndFunction
It would be fair so say over the past few weeks that I have been caught up in all the hype about XPages. So much so that I had forgotten about the thing I was most looking forward to when doing Notes 6 development. For me the single most important recent enhancement to Notes was not XPages or even the new LotusScript editor (in 8.5.1) but the ability to design Notes applications using a Services Oriented Architecture. To me this one new capability ensure Notes future more than anything. Let me explain why..... What Is SOA? There are many definitions out there on SOA. To me SOA extends the concept of Object Oriented Programming to an entirely new level. With OOP we define applications as objects (classes) comprising properties (data) and operations (methods). Now step back and look at all the applications in your organization. Not as a disparate set of applications but rather as a series of components capable of interacting with each other without regard of the application platform in which they were developed. Why Is SOA so Important? Suddenly the application platform is no longer as important as it once was. As long as that platform supports Web Services (and other higher levels of SOA such as property brokers etc.) it really doesn't matter platform what they are written in. Notes applications no longer need to be second class citizens within an IT department. By creating Web Services Notes applications can be accessed by non-Notes applications in the same way as any other SOA application. Likewise Notes applications can also access data from these other applications directly without the need for LEI or other data synching processes. Moving towards an SOA has the potential to solidify a place for Notes as a strategic application development environment. For the great many small-medium sized applications Notes will often offer a clear advantage over alternatives due to its RAD environment. In fact, the need for large applications can be replaced by building a a larger number of smaller components that are intergrated via SOA. And Xpages? Xpages can consume Web services so they are not excluded from this and this may even represent a better way to integrate XPage and non-Xpage Notes applications. Even within a single Notes applications, web services represent a way you can invoke LotusScript code from inside an Xpage. SOA will not happen overnight. Some organizations are much more advanced than others. With Notes 8.x SOA is relatively simple to
implement . So the opportunity is there for Notes developers to lead the way Web service providers were added in Notes 7. Web
Service Consumers and Composite applications were added in Notes 8.0.
My suggestion would be to become familiar with these design elements
and play around with them. I will be developing SOA components as part
of the .Dominio Framework 2.0 and you will probably see as many blogs
from me about SOA as XPages in the coming months. My goal is to
transform my own Notes applications into components and then start
integrating them, in ways that were never possible before.
Version 1.0.2 of the .Domino Framework will contain a new method for setting the Design Template name for one or more design documents. The view used by the framework to display all design documents via the Notes client now has a view action that invokes this method for selected documents.
It's been a while since I shared some code.... The DominoMemo class was developed as a way of simplifying the code an application requires to produce e-mail notifications. The 1.0.2 version of .Domino Framework will contain a new AppendViewAsTable method that allows an application dveeloper to request a table be added to the body of a memo that shows the data in the view along with doclinks to each document. This is similar to the Copy Selected as Table command and NotesNewsletter class. The method also allows the data embedded to be restricted to a single category in the view. The code is provided below for those that wish to adapt it for their specific needs.
'/** ' * Append the data in a views as a table in the body of the e-mail ' * ' * @param View The view to be appended ' * @param Category Single category of view to be included - Nothing = all rows ' */ Sub AppendViewAsTable(View AsNotesView, Category AsVariant) Dim Column AsNotesViewColumn' Specific column in view Dim ColumnIndex AsInteger' Index of the column being processed Dim Doc AsNotesDocument Dim TableColumn AsInteger Dim DocEntry AsNotesViewEntry' View entry for column being processed Dim NoColumns AsInteger Dim RowIndex AsInteger' Row in table being processed Dim RTNav AsNotesRichTextNavigator' Allows navigation within Rich Text Item containing table Dim TableStyle AsNotesRichTextParagraphStyle Dim TableStyles()AsNotesRichTextParagraphStyle' Styles used to format table Dim ViewNav AsNotesViewNavigator' Navigation of view Dim ViewEntries AsNotesViewEntryCollection' Entries in view Try: OnErrorGoto Catch Redim TableStyles(0) Set TableStyles(0)= Session.CreateRichTextParagraphStyle() TableStyles(0).LeftMargin = 0 TableStyles(0).FirstLineLeftMargin = 0 TableStyles(0).RightMargin = 150 ForColumnIndex%= 0 ToUbound(View.Columns) Set Column = View.Columns(ColumnIndex%) If(Not(Column.IsHidden Or Column.IsCategory Or Column.IsHideDetail))Then NoColumns%=NoColumns%+ 1 RedimPreserve TableStyles(NoColumns%) Set TableStyles(NoColumns%)= Session.CreateRichTextParagraphStyle() TableStyles(NoColumns%).LeftMargin = 0 TableStyles(NoColumns%).FirstLineLeftMargin = 0 TableStyles(NoColumns%).RightMargin = Column.Width* 150 EndIf NextColumnIndex% SelectCaseTypename(Category) Case"STRING","STRING ()" Set ViewNav = View.CreateViewNavFromCategory(Category) Set ViewEntries = View.GetAllEntriesByKey(Category) CaseElse Set ViewNav = View.CreateViewNav