SnTT: The ins and outs of ILDDM Binder and Document Security

October 26 2006

ShowAndTell.jpg

I have not done a SnTT post in a while, but I figured this one was something people could use. For the past couple of months, I have been waging a war against IBM Lotus Domino Document Manager ... otherwise known and Domino.Doc. I am working on a client project that is built around the New Product submission idea, but using ILDDM as the way to store the documents. We have lots of documents in the system, from Office to editable PDFs to artwork designed on the Mac to Autocad drawings. Our system allows for the attachments to be put thru workflow (for comments, editing, and approval), but we store everything in ILDDM. Because of the lack of robust workflow in ILDDM, we are using our own enTouch.workflow product. What that means is that we have a document stub that goes thru our workflow, which links to the ILDDM document. Because of the nature of this process, security is very tight. Add in the difficulty of no ILDDM API on the Mac (today) and the lack of any good way to set security on Binders, I decided to do it my own way.
When working with ILDDM, the user sees a Binder as a folder. What a Binder is really is a document in the Binder database. Documents are stored in the Document database.The user just sees two databases on the workspace, with the Document database appending a 1 to the database name.

So what I have done is found a way to set the security on the Binder document and all of the Document documents directly. There is a couple of tricks.

First, I go thru the typical motions of adding an attachment to ILDDM. You do the following:

  • Connect to the ILDDM API via the "Set API = CreateObject("DominoDoc.API")"
  • Connect to the Library via "Call API.SetHttpLogin(ILDDM_UserName, ILDDM_Password)"
  • Connect to the Library via "Set Library = API.GetLibrary(library)"
  • Connect to the File Cabinets collection via "Set FileCabinets = Library.Cabinets"
  • Connect to the File Cabinet via "Set FileCabinet = FileCabinets.ItemByTitle(fcname)"
  • Connect to the Binders collection via "Set Binders = FileCabinet.binders"
  • Connect to the Binder via "Set Binder = Binders.ItemByTitle (bindername)"
  • Connect to the Documents collection via "Set Documents = Binder.Documents"
  • Create a new document via "Set Document = Documents.Add"
  • Set the attachment (need the full path to the attachment) via "Call Document.SetContents(path)"
  • Set the Document Title via "Document.Title = title"
  • Set the Document Description via "Document.Description = desc"
  • Save the Document via "Call Document.Save"
  • Get the Security object of the Document via "Set Binder_Security = Binder.Security"
  • IMPORTANT: Set the All Editors flag to false via "Binder_Security.AllEditorsFlag = False"
  • IMPORTANT: Set the All Readers flag to false via "Binder_Security.AllReadersFlag = False"
  • Save the Document gain via "Call Document.Save"
  • Check in the Document via "Call Document.CheckIn(1, 2, False, "")"

Once we have the document in ILDDM, I write the following information back to the stub document in our workflow system:


With document
               .ILDDMServer = FileCabinet.NotesServer
               .ILDDMBinderDatabaseRepID = FileCabinet.BinderDatabase
               .ILDDMDocumentDatabaseRepID = Binder.DocumentDatabase
               .ILDDMBinderDocumentUID = Binder.UniversalID
               .ILDDMDocumentDocID = Document.UniversalID
              
               Dim docdb As New notesdatabase("","")
              
               Call docdb.OpenByReplicaID(FileCabinet.NotesServer,Binder.DocumentDatabase)
              
               .ILDDMDOcumentDatabaseFileName = docdb.FilePath
End With


This gives me all of the information I need to access the ILDDM Server, the Binder Database, the Binder document, the Document database, and the Document itself without having to use the ILDDM API.

Now, comes the fancy piece. I call an agent in the Binder database that I have created and pass in the workflow stub document as a parameter. Our workflow engine computes the security and writes it into two fields, one Reader and one Author. The agent looks like this (I took out some of the pieces, this is just the relavant piece):


binderserver = document.ILDDMServer(0)
If binderserver = "" Then
        Gotobye
End If

binderdb_value = document.ILDDMBINDERDATABASEREPID(0)
If binderdb_value = "" Then
        Gotobye
End If

documentdb_value = document.ILDDMDOCUMENTDATABASEREPID(0)
If documentdb_value= "" Then
        Gotobye
End If

binderdoc_uid = document.ILDDMBINDERDOCUMENTUID(0)
If binderdoc_uid = "" Then
        Gotobye
End If

Set readerfield = document.GetFirstItem("SFDocReaders")
Set authorfield = document.GetFirstItem("sfdocauthors")

Call binderdb.OpenByReplicaID(binderserver,binderdb_value)
If binderdb.IsOpen = False Then
        Print"Binder Database not opened"
        Gotobye
End If

Call documentdb.OpenByReplicaID(binderserver,documentdb_value)
If documentdb.IsOpen = False Then
        Gotobye
End If

Set binderdoc = binderdb.GetDocumentByUNID(binderdoc_uid)
If binderdoc Is Nothing Then Goto bye
     
Call binderdoc.removeitem("ComputedAuthors")
Call binderdoc.RemoveItem("DocAuthors")
Call binderdoc.RemoveItem("ComputedReaders")
Call binderdoc.removeitem("DocReaders")
       
binderdoc.computedauthors = document.sfdocauthors

binderdoc.docauthors = document.sfdocauthors
binderdoc.computedreaders = document.sfdocreaders
binderdoc.docreaders = document.sfdocreaders

Set binder_computedreaders_item = binderdoc.GetFirstItem("ComputedReaders")
Set binder_computedauthors_item = binderdoc.GetFirstItem("ComputedAuthors")

Call binder_computedreaders_item.AppendToTextList("[Administrator]")

binder_computedreaders_item.IsReaders True
binder_computedauthors_item.IsAuthors True

Call binderdoc.Save(True, False)
'update documents

document.sfdocauthorreader = Arrayappend(document.sfdocauthors,document.sfdocreaders)
document.sfdocauthorreader = Arrayunique(document.sfdocauthorreader)
document.sfdocauthorreader = Fulltrim(document.sfdocauthorreader)

Set document_computedreaders_item = document.GetFirstItem("sfdocauthorreader")

Call document_computedreaders_item.AppendToTextList("[Administrator]")
'update versions        

Set docview = documentdb.GetView("vaDocsByBinderID")
Set doccol = docview.GetAllDocumentsByKey(binderdoc_uid)

If doccol.Count > 0 Then
        Calldoccol.StampAll ("ComputedAuthors", document.sfdocauthors)
        Calldoccol.StampAll("ComputedReaders", document.sfdocauthorreader)
End If
'update drafts

Set draftview = documentdb.GetView("DraftDocsByBinderID")
Set draftcol = draftview.GetAllDocumentsByKey(binderdoc_uid)

If draftcol.Count > 0 Then
        Calldraftcol.StampAll ("ComputedAuthors", document.sfdocauthors)
        Calldraftcol.StampAll("ComputedReaders", document.sfdocauthorreader)
        Calldraftcol.StampAll ("ComputedDraftEditors", document.sfdocauthors)
End If


So as you can see, I set the Binder document security manually and update all of the documents with the correct fields. Since ILDDM handles the database ACL itself, I do not have to worry about that.

I only had to create one new Design Element in ILDDM for this, and that is the "DraftDocsbyBinderID" view. That view is just a copy of the "vaDocsByBinderID" with the Selection formula changed to include "& @IsResponseDoc".

While this is definitly a righteous hack as Rocky would say, it works perfectly. Next up is to figure out how to create a File Cabinet programatically, since the ILDDM API does not include that.

3 Responses to “SnTT: The ins and outs of ILDDM Binder and Document Security”

  1. 1) Timothy Briley says:

    I actually passed the Lotus Dom.Doc cert test about six years ago. I think Barbara Bowen said that I was the first one to take it in quite a while. That said, I never really liked the product. I don't know if things have changed, but at the time, it was faster to access a doc through a browser than the Notes client. The API was a real treat too.

    Sounds like things haven't gotten any better.

  2. 2) Adam Brown says:

    David I would be keen to hear if the performance of Domino.Doc has improved over the last 6 years. As per Tim's comment I too found it faster to access a doc via a browser than thru a Notes client. This was off course about 6 years ago as well. We even had one client that chose to use it thru a browser instead of the Notes client for this reason.

    I really havn't played with the product for the last 4-5 years so I am sure it has improved a lot. I attended a session at LotusSphere on Dom.Doc this year just out of interest and they have obviously done a lot to the product however I would be keen to hear that the speed is dramatically better!! We have been promoting another business partners Notes based document management system for quite a while and while it is pretty good I do like some of the features from Dom.Doc. The speed jsut killed it for us though.

  3. 3) Adam Brown says:

    Oops. Sorry John. Don't know where I got David from!

Leave a Reply