Domino supports a number of techniques to establish relations among documents. VisualAge Smalltalk Domino Connection implements two important models: response documents and doclinks.
Practically, using the Notes client software, a response document is created from a special form, which automatically links the new document to the one which is selected in the currently open view. Technically, a response document is a document that contains a reference to another document in a field named '$REF'. The reference is established using the parent documents note ID, which uniquely identifies the parent note.
Note: | Parent-child relationships can be visualized using special views. See your Domino designer documentation on how to set up views to show response documents properly. |
To establish a parent-child or parent-response relationship between documents, you need to have two documents from the same database. There is only a one way assignment: from child to parent.
Here is a step-by-step example how to establish a parent-child relationship between two documents:
| parentNote childNote connection database | "Startup runtime system" AbtLnEnvironment startUp. "Create a connection t local databases" connection := AbtLnConnection local. "Open one of the sample databases provided with the feature" database := connection openDatabase: 'VASAMPLE\VASAMPLE.NSF'. "Create a new document and associate it with the 'Main Topic' form. Execute default value formulas" parentNote := database newNoteFromComputedForm: 'Main Topic'. "Set the Subject field to 'ParentNote'." parentNote at: 'Subject' put: 'ParentNote'. "Store the document. Execute input translation and input validation formulas" parentNote store. "Create a new document and associate it with the'Response' form. Execute default value formulas" childNote := database newNoteFromComputedForm: 'Response'. "Set the Subject field to 'Response'." childNote at: 'Subject' put: 'Response'. "Establish the parent/child relationship" childNote becomeResponseNoteTo: parentNote. "Store the document" childNote store. "Close the database" database close. "Shutdown runtime system" AbtLnEnvironment shutDown.
There are two ways to identify child documents to a parent. You can either use a view that displays the response hierarchy and iterate using the children protocol with the tree nodes. Or you can use the responseNotes protocol with an AbtLnNote instance.
Here is a step-by-step example how to retrieve the number response documents of each Main Topic document in a discussion database.
| allParents connection database | "Startup runtime system" AbtLnEnvironment startUp. "Create a connection t local databases" connection := AbtLnConnection local. "Open one of the sample databases provided with the feature" database := connection openDatabase: 'VASAMPLE\VASAMPLE.NSF'. "Read all the main topic documents" allParents := database allNotesFromQuery: 'Form="MainTopic"'. "Print the subject of each document that has responses and print the number of responses to each document" allParents do: [ :e | | responses | ( responses := e responseNotes) isEmpty ifFalse: [ Transcript nextPutAll: ('The document : ', (e fill at: 'Subject')); nextPutAll: (' has ', responses size printString, ' response documents'); cr. ] ]. "Close the database" database close. "Shutdown runtime system" AbtLnEnvironment shutDown. AbtLnEnvironment
You can certainly access each individual response document that is returned from the responseNotes message.
Another often used technique to establish relationships between documents is creating doclinks. A doclink is a reference to another document in the same or another database, even to a document on another server. A doclink uses the information of a document's unique ID to identify the linkage. When using the Notes client software, a doclink is established through a special "Copy as Link" option.
There is limited support for the creation of doclinks in Domino Connection. You can create one or more links if you have a RTF field available in your document , but you cannot put other RTF contents into the same field. Neither can you add a doclink to an RTF field in a preexisting document without deleting the fields former contents.
A doclink can be established with a simple protocol. You need a database view to identify the note to be linked and another note which receives the link.
Note: | A view is required due to the structure of the API. Thus you can only set up doclinks to documents which are contained in a database view at link-time. |
The following code samples shows you how to create a doclink:
| localConnection hostDB linkDB hostNote linkDbViewNote linkNote rtfField | "Startup runtime system" AbtLnEnvironment startUp. "Create a local connection for the sample databases" localConnection := AbtLnConnection local. "open the database which contains the note to be linked to a new document" linkDB := localConnection openDatabase: 'vasample\vaforms'. "Retrieve the corresponding view note" linkDbViewNote := linkDB viewNoteByName: 'SimpleView'. "Get an arbitrary document from the link database" linkNote := linkDB allNotes first fill. "Open the database that will host the note containing the doclink" hostDB := localConnection openDatabase: 'vasample\vasample'. "Create a new note based on the Main Topic form" hostNote := hostDB newNoteFromForm: 'Main Topic'. "Set the Subject field to help you identify the document" hostNote at: 'Subject' put: 'A new Doclink'. "Get the Body field from the note" rtfField := hostNote itemAt: 'Body'. "Set the Body field to accept binary contents, for example a doclink" rtfField binary: true. "Now add the note to be linked" rtfField addDocLinkFor: linkNote in: linkDbViewNote . "Store the new Note" hostNote store. "Close the open databases" hostDB close. linkDB close. "Shutdown runtime system" AbtLnEnvironment shutDown.
You can resolve doclinks like shown in the following example:
Note: | The example is based on the sample databases provided with Domino Connection. It resolves a doclink between the vasample database and the vamail database. Make sure you have the sample databases installed on your local workstation in the vasample subdirectory if you want to execute the sample code. Be aware that if you have changed the databases contents, the samples might not work due to the presence or absence of documents. |
| database categoryView category noteWithLink linkedNote | "Startup runtime system" AbtLnEnvironment startUp. "Open a local sample database provided with the feature" database := AbtLnConnection local openDatabase: 'vasample\vasample'. "Open the 'By Category' view of the database" categoryView := database openViewRebuild: 'By Category'. "Expand the view to the first category level and select the category node with the category named: 'Programming Examples'" category := categoryView root children detect: [ :node | node category = 'Programming Examples' ]. "Expand the selected category level and select the first node, which is a document in this case" noteWithLink := category children first asNote. "If the note is present, find out if there is a link in the note" noteWithLink notNil ifTrue: [ "Read the documents contents and check for doclinks" noteWithLink fill allDocLinks isEmpty ifFalse: [ "Resolve the doclink" linkedNote := noteWithLink allDocLinks first resolve. "Print the linked note to the Transcript window" Transcript nextPutAll: linkedNote printString; cr. ]. ]. "Close the view" categoryView close. "Close the database" database close. "Shut down runtime system" AbtLnEnvironment shutDown.
Be aware that the linked note is returned as "read only" document. If you want to modify the contents of the linked document, you have to retrieve it from the corresponding database. Look at the following code fragment that shows you how to open the note:
"code fragment .... same code as previous sample" ........ "Resolve the doclink" linkedNote := noteWithLink allDocLinks first resolve. "get the database the document resides in" linkDB := linkedNote database. "read the noteid from the document header" linkedNoteID := linkedNote header noteID. "open the database that contains the link document" linkDB open. "open the actual document for editing" likedNoteToEdit := AbtLnNote fromID: linkedNoteID inDatabase: linkDB. .......