Friday, March 25, 2016

A Java Agent Which Extracts a File Attachment to the D:\ Drive of the Server

Recently I was given an assignment to extract a file from a Notes document and place it on the server’s D:\ drive.  The file would then be picked up and delivered elsewhere.
I was originally asked to place this file in a network share but I knew that Notes security only allows access to the file system of the server itself.  I decided to create a scheduled java agent to perform the extract because I just couldn’t bring myself to create something new in Lotusscript.


Each document only contains a single attachment so I didn’t have to worry about multiple attachments.  The code would have to be modified to accommodate that use case.  The attachment directory also needed to be kept in a keyword document in case the location is moved at a later point in time.


The code also is robust enough to write a status back to the database whether the extract was successful or not.  The database contains a view has a column that reports back the result.
The agent first checks whether the file is already there, and then fails if it is. Obviously it is impossible for one to have two files of the same name in the same directory.  The agent then performs the extract and then verifies that the file is now in the directory. 

The Code

The code here is self explanatory so I am don't think there is a need to do a code explanation. The comments tell what is happening.

import java.util.Enumeration; 
import java.util.Vector; 

import lotus.domino.*; 

public class JavaAgent extends AgentBase { 

    public void NotesMain() { 

      try { 
          Session session = getSession(); 
          AgentContext agentContext = session.getAgentContext(); 
          Database db = session.getCurrentDatabase(); 
          //Get Keyword containing attachment location 
          String searchKWString = "SELECT Form = 'frmKeyword' & Keyword = 'AttachmentDirectory'"; 
          DocumentCollection locationCol =; 
          Document locationDoc = locationCol.getFirstDocument(); 
          String location = locationDoc.getItemValueString("Choices"); 
          //Get all Unprocessed Documents 
          String searchString = "SELECT Form = 'Document' & VCC_Upload != 'Y'"; 
          DocumentCollection unprocessedCol =; 
          Document doc = unprocessedCol.getFirstDocument(); 
          Document tempDoc = null; 
          while(doc != null){ 
                  //Extract attachment to location on server. Documents only have one attachment. 
                  Item item = null; 
                  Vector attachmentNames = new Vector(); 
                  Enumeration itemEnum = doc.getItems().elements(); 
                  while (itemEnum.hasMoreElements()){ 
                          item = (Item) itemEnum.nextElement(); 
                      if (item.getType() == Item.ATTACHMENT) { 
                  String attachmentName = (String) attachmentNames.firstElement();                 
                  EmbeddedObject eo = doc.getAttachment(attachmentName); 
                  if(eo != null){ 
                          //Check if File already present in folder 
                          File file = new File(location + eo.getName()); 
                          boolean existsBefore = file.exists(); 
                          boolean existsAfter = false; 
                                  //Perform Extract               
                              eo.extractFile(location + eo.getName()); 
                              existsAfter = file.exists(); 
                              //Mark document as processed 
                          doc.appendItemValue("VCC_Upload", "Y"); 
                          doc.appendItemValue("Upload_Time", new java.util.Date().toString()); 
                          doc.appendItemValue("UploadMessage", "Upload Successful"); 
                          } else { 
                          //Mark document as unsuccessful 
                                  doc.appendItemValue("VCC_Upload", "Y"); //prevents document from being considered in future runnings 
                      doc.appendItemValue("Failure_Time", new java.util.Date().toString()); 
                      doc.appendItemValue("UploadMessage", "Extract Failed Due to file being extracted previously"); 

                          if(!existsBefore && !existsAfter){ 
                         //Mark document as unsuccessful 
                      doc.appendItemValue("VCC_Upload", "N"); 
                      doc.appendItemValue("Failure_Time", new java.util.Date().toString()); 
                      doc.appendItemValue("UploadMessage", "Extract Failed"); 
                //Get next unprocessed document 
              tempDoc = unprocessedCol.getNextDocument(doc); 
              doc = tempDoc; 
      } catch(Exception e) { 


I realize that this is a limited use case, and is certainly nothing cutting edge, but hopefully this is of use to someone or future me when they need it.  A big hat tip to Jesse Gallagher who pointed me in the right direction.