zoukankan      html  css  js  c++  java
  • How to read a text file attached to a Lotus Notes Document WITHOUT detaching it?

    One of the biggest problems when dealing with file attachments in Lotus Notes documents is that you can't detach the files on the server. This is due to a setting on the Public Names & Address Book on the server. Usually the server's administrator will not allow the use of unrestricted agents so the agent's will not touch any file on the server (which is a good idea).

    But in some cases you will need to detach a file on the server to work with. If the administrator won't put you in the group who are authorized to use unrestricted agents, or not willing to sign the agent then you will need to find a workaround. In some cases if you are using a server which is hosted by a 3rd party you will not always have the rights to use unrestricted Lotus Script or Java agents.

    While looking for a solution on the web, I have tumbled over several articles where people are trying to do the same thing, for example this article on Techtarget.com: Can you use LotusScript to read a text file attached to a Notes doc?. One idea to get started is to check this excellent article from Jake Howlett on Codestore.net: Generating File Attachments in Agents Without Unrestricted Rights

    I wanted to have a simpler solution and also have a better understanding of what has to be done, so I'm sharing this easy to understand workaround, it is simply for the Lotus Notes developers out there to get an idea on how to do it.

    First, there is no way to read a file attached to a Lotus Notes Document using only LotusScript, you can get the attachments filename, delete or add attachment but not actually work with the attached file without detaching it. The solution is to get some help with a Java agent that allows us to do a lot more stuff on Lotus Notes & Domino.

    We are going to use two Lotus agents to do that, the first one will be a LotusScript agent to get the data from the Notes Document and pass it to the Java agent which will read the file attached and return a string back to the LotusScript agent.

    The first problem you will face by using two different agent's is to find a way to pass some data from one agent to the other, you could write the parameters you need in the Lotus Notes document but then you will face some other problems, for example the document date will be modified and the document will have to be replicated over all the replica's. So when running the LotusScript agent, we will create a temporary Parameter document and write all the parameter needed in some fields.

    You will find below the LotusScript agent listing, in this example we want to get the data of the attached file name "test0.txt". This agent will create a parameter document and put the Document ID in a field, as well as the name of the file attachment to read.

    Then we will pass this document to the Java agent and it will write the

    Listing 1: LotusScript Agent: "ReadAttachmentLS"

    Sub Initialize
       Dim s As New NotesSession
       Dim db As NotesDatabase
       Dim workspace As New NotesUIWorkspace
       Dim uidoc As NotesUIDocument
       Set uidoc = workspace.CurrentDocument
       Dim doc As NotesDocument
       Set doc = uidoc.Document
       Dim agent As NotesAgent
       Set db = s.CurrentDatabase
    
       'In this example we will read the data of a file attachment named 
       '"test0.txt"
       'This is done by calling a Java agent, which will read the attachment 
       'WITHOUT detaching
       'the file to the hard disk
       Dim theFileAttachmentToRead As String
       theFileAttachmentToRead = "test0.txt"
       
       'Populate the parameters to be used by the Java agent
       'As described here:
       'http://www.ibm.com/developerworks/lotus/library/ls-Run_and_RunOnServer/
       'index.html
       'It is off course better to create a parameter document as described in the
       'above URL, like this, for example,
       'the modification date won't be modified
       
       'Create document that will be used for parameter passing 
       Dim parameterDoc As NotesDocument
       Set parameterDoc = db.CreateDocument 
       
       'Add the field that will contain the value filename & Universal ID
       Dim item As NotesItem 
       Set item = parameterDoc.AppendItemValue("Filename", theFileAttachmentToRead)
       Set item = parameterDoc.AppendItemValue("UniversalID", doc.UniversalID)
       
       'Save the document 
       Call parameterDoc.save(True, False)
       
       'Set the parameter value of the parameter document
       Dim paramid As String
       paramid = parameterDoc.Noteid
       
       Set agent = db.GetAgent("ReadAttachmentJava")
       'Start agent and pass note ID of document
       'Use agent.RunOnServer(paramid) to run the agent on the server
       If agent.Run(paramid) = 0 Then
          Print "Agent ran - Success"
       Else
          Print "Agent did not run - Failure"
       End If
       
       'Delete in-memory document. This is necessary because we need to reload 
       'the document in order to get the latest data which the Java Agent has 
       'written into the parameter document
       Delete parameterDoc 
       
       'Get the result from the parameter document (the data from the file 
       'attachment)
       Dim theResult As String
       Set parameterDoc = db.GetDocumentByID(paramid)
       theResult = parameterDoc.Result(0)
       
       'Do whatever you need with the data
       'Your code goes here
       Print "parameterDoc: Result=" + theResult
       
       'When finished delete the temporary parameter document
       Call parameterDoc.RemovePermanently(True)
    End Sub


    Now we need to create a Java agent, which will read the parameter document to get the document ID and the name of the attachment to read from, we will use standard Java IO stream function to read the file, once it is read, we write the content in a result field in the previously passed parameter document.

    Listing 2: Java Agent: "ReadAttachmentJava"

    import lotus.domino.*;
    import java.io.BufferedReader;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    
    public class JavaAgent extends AgentBase {
       public void NotesMain() {
          try{
             Session session = getSession();
             AgentContext agentContext = session.getAgentContext();
             Database db = agentContext.getCurrentDatabase();
             Agent agent = agentContext.getCurrentAgent();
    
             //Get document used for passing data
             Document paramDoc = db.getDocumentByID(agent.getParameterDocID());
    
             //Get the Universal ID and the Document where the attachment
             //is located
             String UniversalID = paramDoc.getItemValueString("UniversalID");
             Document doc = db.getDocumentByUNID(UniversalID);
    
             //Get the attachment filename from the parameter document
             String filename = paramDoc.getItemValueString("Filename");
             EmbeddedObject obj = doc.getAttachment(filename);
     
             String theJavaResult = "";         
               if (obj != null) {
                paramDoc.replaceItemValue("theJavaResult", "Found " + 
                obj.getName());      
             }
     
             java.io.InputStream is = obj.getInputStream();
             String theResult = "";
             if (is != null) {
                //read the stream of the file
                theResult = convertStreamToString(is);
             } else 
                paramDoc.replaceItemValue("theJavaResult", "No 
                Attachment InputSource!");      
             //Destroy object
             obj.recycle();
    
             //Save the parameter Doc with the result
             //put the result into a temporary field
             paramDoc.replaceItemValue("Result", theResult);
             paramDoc.save();
          }
          //Catch if something wrong happens from Notes side like,
          //Database/view failed to open or invalid formula etc
          catch(NotesException e) {System.out.println(e.id + " " + e.text);}
          //Usual Java Exception class
          catch(Exception e) { e.printStackTrace(); }
       }
    
       public static String convertStreamToString(InputStream is) throws 
       Exception {
          BufferedReader reader = new BufferedReader(new InputStreamReader(is));
          StringBuilder sb = new StringBuilder();
          String line = null;
          while ((line = reader.readLine()) != null) {
             sb.append(line + "\n");
          }
          is.close();
          return sb.toString();
       }
    }


    Once the Java agent has finished, we return to the LotusScript agent and read the result field from the parameter document. There is the place where you write the code you want your agent to do with the data. Don't forget to delete the parameter document if you don't need it anymore.

    So, I hope this will give you a simple idea on how you can read file attachments without detaching them and how to pass parameters from one agent to another.

    Some of you will ask, why not use a Java Library instead of a Java agent? Well because at this time, LS2J (IBM's LotusScript To Java), won't allow you to have access to the documents or uidocuments directly, you will need to use a Java agent in order to get the NoteID from LotusScript.

    This code has been tested on Lotus Domino & Notes version > 8.x.

    Best regards,
    Adel Habib
  • 相关阅读:
    curl continue
    actor
    nginx
    jmx additional port
    diff
    lsof
    zk reconnect
    Python:Python基础(一)
    Python:初识Python(二)
    Python:初识Python(一)
  • 原文地址:https://www.cnblogs.com/hannover/p/2467205.html
Copyright © 2011-2022 走看看