4

I have a 'small' problem. In a database documents contain a richtextfield. The richtextfield contains a profile picture of a certain contact. The problem is that this content is not saved as mime and therefore I can not calculate the url of the image.

I'm using a pojo to retrieve data from the person profile and use this in my xpage control to display its contents. I need to build a convert agent which takes the content of the richtextitem and converts it to mime to be able to calculate the url something like

http://host/database.nsf/($users)/D40FE4181F2B86CCC12579AB0047BD22/Photo/M2?OpenElement

Could someone help me with converting the contents of the richtextitem to mime? When I check for embedded objects in the rt field there are none. When I get the content of the field as stream and save it to a new richtext field using the following code. But the new field is not created somehow.

System.out.println("check if document contains a field with name "+fieldName);
        if(!doc.hasItem(fieldName)){
            throw new PictureConvertException("Could not locate richtextitem with name"+fieldName);
        }


        RichTextItem pictureField = (RichTextItem) doc.getFirstItem(fieldName);

        System.out.println("Its a richtextfield..");
        System.out.println("Copy field to backup field");

        if(doc.hasItem("old_"+fieldName)){

            doc.removeItem("old_"+fieldName);

        }


        pictureField.copyItemToDocument(doc, "old_"+fieldName);     

//      Vector embeddedPictures = pictureField.getEmbeddedObjects();
//      System.out.println(doc.hasEmbedded());
//      System.out.println("Retrieved embedded objects");
//      if(embeddedPictures.isEmpty()){
//          throw new PictureConvertException("No embedded objects could be found.");
//      }
//      


//      EmbeddedObject photo = (EmbeddedObject) embeddedPictures.get(0);
        System.out.println("Create inputstream");

        //s.setConvertMime(false);
        InputStream iStream = pictureField.getInputStream();
        System.out.println("Create notesstream");
        Stream nStream = s.createStream();
        nStream.setContents(iStream);

        System.out.println("Create mime entity");

        MIMEEntity mEntity = doc.createMIMEEntity("PictureTest");
        MIMEHeader cdheader = mEntity.createHeader("Content-Disposition");
        System.out.println("Set header withfilename picture.gif");

        cdheader.setHeaderVal("attachment;filename=picture.gif");
        System.out.println("Setcontent type header");
        MIMEHeader cidheader = mEntity.createHeader("Content-ID");
        cidheader.setHeaderVal("picture.gif");
        System.out.println("Set content from stream");
        mEntity.setContentFromBytes(nStream, "application/gif", mEntity.ENC_IDENTITY_BINARY);
        System.out.println("Save document..");

        doc.save();
        //s.setConvertMime(true);


        System.out.println("Done");

        // Clean up if we are done..

        //doc.removeItem(fieldName);
jjtbsomhorst
  • 1,667
  • 11
  • 28
  • Have you tried to change the RT field to mime and re-save the documents? – Thomas Adrian Mar 07 '12 at 15:57
  • 1
    Yes, that does the trick when I do it manually. But there are +/- 200 documents and I dont want to save and close them by and if I dont need to ;) – jjtbsomhorst Mar 07 '12 at 16:15
  • Can you do doc.computewithform(...) and save them, and after that access the mime data in your java code? – Thomas Adrian Mar 07 '12 at 16:33
  • I haven't tested that yet I will do – jjtbsomhorst Mar 07 '12 at 19:28
  • if your can get to the url when you save the document manually I see no reason why you should not be able to do it programmatically. – Thomas Adrian Mar 07 '12 at 19:30
  • (still haven't tried the computewith form..) Well thats just the trick ;) I tried a lot today and I couldnt get it to work. The url is calculated and only legible for rt fields which are already mime. – jjtbsomhorst Mar 07 '12 at 20:58
  • Have you tried using a Formula agent: **@Command( [ViewRefreshFields] )** Run on selected documents, from the Notes Client. If I remember correctly, it does a little more than ComputeWithForm. – Tommy Valand Mar 08 '12 at 07:03

3 Answers3

2

Its been a little while now and I didn't go down the route of converting existing data to mime. I could not get it to work and after some more research it seemed to be unnecessary. Because the issue is about displaying images bound to a richtextbox I did some research on how to compute the url for an image and I came up with the following lines of code:

function getImageURL(doc:NotesDocument, strRTItem,strFileType){
    if(doc!=null && !"".equals(strRTItem)){
        var rtItem = doc.getFirstItem(strRTItem);
        if(rtItem!=null){
            var personelDB = doc.getParentDatabase();
            var dbURL = getDBUrl(personelDB);
            var imageURL:java.lang.StringBuffer = new java.lang.StringBuffer(dbURL);

            if("file".equals(strFileType)){
                var embeddedObjects:java.util.Vector = rtItem.getEmbeddedObjects();
                if(!embeddedObjects.isEmpty()){
                    var file:NotesEmbeddedObject = embeddedObjects.get(0); 

                    imageURL.append("(lookupView)\\");
                    imageURL.append(doc.getUniversalID());
                    imageURL.append("\\$File\\");
                    imageURL.append(file.getName());
                    imageURL.append("?Open");

                }
            }else{              
                imageURL.append(doc.getUniversalID());
                imageURL.append("/"+strRTItem+"/");
                if(rtItem instanceof lotus.domino.local.RichTextItem){
                    imageURL.append("0.C4?OpenElement");
                }else{
                    imageURL.append("M2?OpenElement");
                }
            }
            return imageURL.toString()
        }
    }
}

It will check if a given RT field is present. If this is the case it assumes a few things:

  • If there are files in the rtfield the first file is the picture to display
  • else it will create a specified url if the item is of type Rt otherwhise it will assume it is a mime entity and will generate another url.
jjtbsomhorst
  • 1,667
  • 11
  • 28
0

The issue cannot be resolved "ideally" in Java.

1) if you convert to MIME, you screw up the original Notes rich text. MIME allows only for sad approximation of original content; this might or might not matter.

If it matters, it's possible to convert a copy of the original field to MIME used only for display purposes, or scrape it out using DXL and storing separately - however this approach again means an issue of synchronization every time somebody changes the image in the original RT item.

2) computing URL as per OP code in the accepted self-answer is not possible in general as the constant 0.C4 in this example relates to the offset of the image in binary data of the RT item. Meaning any other design of rich text field, manually entered images, created by different version of Notes - all influence the offset.

3) the url can be computed correctly only by using C API that allows to investigate binary data in rich text item. This cannot be done from Java. IMO (without building JNI bridges etc)

Normunds Kalnberzins
  • 1,213
  • 10
  • 20
0

Not sure if this is an answer but I can't seem to add comments yet. Have you verified that there is something in your stream?

if (stream.getBytes() != 0) {

Vic
  • 367
  • 2
  • 10