Java: attach to document, not field?

We have a substantially-complex Domino web application, supporting a 24x365 team since 2003. The back-end processing is handled in Java.

The system allows addendums to documents, implemented by copying the original document’s data into a new document which can then be edited. Attachments must also be copied to the addendum.

Over the Web, a file-upload control attaches files to the document. Programmatically, we can only attach files to Rich-Text fields (unless I’ve missed something). I would like to avoid searching for attachments on the document and in Rich-Text fields when creating an addendum.

During WebQueryOpen, nd_Addendum.appendItemValue( ni_AttachmentFromOriginal ) creates “phantom” attachments: they show up but do not work nor save. And nd_Addendum.copyItem( ni_AttachmentFromOriginal ) cannot be used for copying attachments. The tried-and-true method of exporting and re-importing works but I’ll need to scan all Items with Item.getType() == Item.ATTACHMENT and also scan rt_Attachments.getEmbeddedObjects().

Does anyone have an idea on how to attach to the document rather than a Rich-Text field with Java?

Thanks.

Subject: Java: attach to document, not field?

Stan Rogers, are you there?

In one of your other posts, you state that a file attached to a document actually resides (at an offset) within a Rich Text field. I’ve already tried casting the $FILE item to a RichTextItem; got an illegal cast exception. Furthermore, I can create (with Java) only one $FILE RichTextItem whereas it’s possible to have many $FILE Items.

Still, I’m hoping to copy attachments from one document to another (without copyToDatabase(…) ). Is there any way to use embedObject with a $FILE Item?

Subject: RE: Java: attach to document, not field?

The answer is simpler than you might think – create a rich text item on the document, attach the file through the rich text item using the normal methods, then remove the rich text item. Voilà – a V2-style attachment.

Subject: RE: Java: attach to document, not field?

Unbelievable! Solution #7 was to just move all attachments into a rich text item during WebQuerySave and handle the display myself, but I moved on to (getting desperate) Solution #8 instead: use Document.copyToDatabase(…) to create a raw addendum. That involved AJAX; I see you’ve been busy there, too.

Thanks very much for the help. I’ll give it a whirl.

Subject: Gave it a whirl; fell off!

I hate to invoke the magic words again, Stan Rogers, but it didn’t work. I think describing the implementation will confirm my suspicion (at the bottom).

Open a new, blank document that will inherit from a parent:

…?OpenForm&ParentUNID=…

Code to attach files in agent specified in Form’s WebQueryOpen:

[Set nd_ThisIncident to the document context - for the Form just opened]

[Use ParentUNID to initialize nd_ParentIncident]

[Set ni_ParentIncident to an Item of type ATTACHMENT on nd_ParentIncident]

// create a rich text item on the document

rt_File = nd_ThisIncident.createRichTextItem( “XFILE” );

// attach the file through the rich text item using the normal methods

eo_Attachment = nd_ParentIncident.getAttachment( ni_ParentIncident.getValueString() );

s__TemporaryFilename = eo_Attachment.getSource();

eo_Attachment.extractFile( s__TemporaryFolder + S__BACKSLASH + s__TemporaryFilename );

rt_File.embedObject( EmbeddedObject.EMBED_ATTACHMENT, null, s__TemporaryFolder + S__BACKSLASH + s__TemporaryFilename, s__TemporaryFilename );

// then remove the rich text item.

// nd_ThisIncident.removeItem( “XFILE” );

rt_File.remove();

// Voilà

Je ne peux pas les trouver.

Attachments show up the screen only when their rich text item (named $FILE) is not removed. But we already know the links don’t work in that scenario.

The thought process that led me to the Document.copyToDatabase(…) solution was:

  1. The attachments to the original document now live on the server, but

  2. When creating a new document over the web, can the web server really copy the attachments into the in-memory document?

Subject: RE: Gave it a whirl; fell off!

The document would need to be saved between creating the attachment and removing the rich text item you used to create the attachment. Or you could simply make sure that there is never a UI widget corresponding to the rich text field you are using for attachments, which would force the attachments to be treated like V2-style attachments in the UI.

Subject: RE: Gave it a whirl; fell off!

Sadly, I couldn’t get these to work.

The first idea has the same disadvantage as Document.copyToDatabase(…): a real document is created and saved. Whereas a document created with …?OpenForm&ParentUNID=… can be abandoned (via the Back button, for example) with no problem, both the first idea and copyToDatabase(…) require clean-up if the document is abandoned. Still, that’s better than nothing.

I tested by trying to append to an existing document, using a Notes Client:

[Set nd_Original to the Notes Document that will hold the attachment I want to copy]

rt_File1 = nd_Original.createRichTextItem( “FILE1” );

eo_File1 = rt_File1.embedObject( EmbeddedObject.EMBED_ATTACHMENT, null, “d:\uc_midi.gif”, “uc_midi.gif” );

nd_Original.save( true, true );

nd_Original.removeItem( “FILE1” );

nd_Original.save( true, true );

The file did not remain attached during repeated attempts.

I commented-out the last two lines to verify the file was being attached. Then I accidently attached the file again, using a different RichTextItem. Darn. I removed the additional RTI by commenting-out the first save and re-activating the last two lines. Suddenly two(?) $FILE Items appeared - success! I went on to remove the first RTI - and both $FILE Items disappeared.

Further testing along these lines seems to show at least one RTI must remain:

rt_File1 = nd_Original.createRichTextItem( “FILE1” );

rt_File2 = nd_Original.createRichTextItem( “FILE2” );

eo_File1 = rt_File1.embedObject( EmbeddedObject.EMBED_ATTACHMENT, null, “d:\uc_midi.gif”, “uc_midi.gif” );

eo_File2 = rt_File2.embedObject( EmbeddedObject.EMBED_ATTACHMENT, null, “d:\userlist.txt”, “userlist.txt” );

nd_Original.save( true, true );

nd_Original.removeItem( “FILE1” );

//nd_Original.removeItem( “FILE2” );

nd_Original.save( true, true );

This leaves one $FILE Item and the FILE2 RTI - both containing userlist.txt. So I can create a $FILE Item via an RTI (with the help of a second, temporary RTI) but the RTI has to stay as well.

The second idea works in the Notes Client UI? There is no (nor has there ever been a) UI widget(?) for any of these RTIs on the form, but no $FILE Items were automatically created when I ran the agent from a view. But it’s a moot point as this needs to work using a Web Client.

Thanks for your help though, Stan. It will come in handy sooner or later.