com.hcl.domino.db Advanced Topics
This page describes advanced topics of Java library.
Attachments
Reading attachments
The database APIs Database::getReadAttachmentMgrByUnid(), Database::getReadAttachmentMgr() can be used to read the attachments. These methods returns object of ReadAttachmentMgr class.
try {
OptionalFileNames files = new OptionalFileNames(Sets.newHashSet("demo1.txt", "demo2.txt", "demo3.txt"));
ReadAttachmentMgr readAttMgr = database.getReadAttachmentMgrByUnid("49CDF4368D68B2C185258359007B465C", files);
InputStream iStream = readAttMgr.readFile();
if (iStream != null) {
AttachmentInputStream ais = (AttachmentInputStream)iStream;
System.out.println("Reading attachment- name: " + ais.getFileName() + "\t size in bytes: "+ ais.getFileSize());
while(iStream.available() > 0) {
System.out.print((char)(byte)iStream.read());
}
iStream.close();
}
} catch(IOException|InterruptedException|DocumentException ex) {
System.out.println(ex.getMessage());
}
Writing attachments
The database APIs Database::getWriteAttachmentMgr() can be used to write the attachments. These methods returns object of WriteAttachmentMgr class.
try {
WriteAttachmentMgr writeAttMgr = database.getWriteAttachmentMgr();
OutputStream out = writeAttMgr.addFile("49CDF4368D68B2C185258359007B465C", "demo.txt");
out.write("Demo purpose".getBytes());
// Second attachment, closes previous attachment if not closed explicitly.
out = writeAttMgr.addFile("49CDF4368D68B2C185258359007B465C", "demo2.txt");
out.write("Demo purpose".getBytes());
out.close();
List<AttachmentInfo> attachmentInfoList = writeAttMgr.end();
for (AttachmentInfo attachmentInfo : attachmentInfoList) {
System.out.println("File name: " + attachmentInfo.getFileName());
System.out.println("File size: " + attachmentInfo.getFileSize());
System.out.println("Error code: " + attachmentInfo.getErrorCode());
System.out.println("Error message: " + attachmentInfo.getErrorMessage());
}
} catch(IOException | BulkOperationException ex ) {
System.out.println(ex.getMessage());
}
Deleting attachments
The database APIs Database::deleteAttachments(), Database::deleteAttachmentsByUnid() can be used to delete the attachments. These methods returns ListenableFuture of list of AttachmentInfo object.
try {
OptionalFileNames files = new OptionalFileNames(Sets.newHashSet("demo.txt","demo2.txt"));
ListenableFuture<List<AttachmentInfo>> response = database.deleteAttachments("Form = 'Contact' and FirstName = 'James'", files);
List<AttachmentInfo> attachments = response.get();
for (AttachmentInfo attInfo : attachments) {
System.out.println("Unid " + attInfo.getUnid());
System.out.println("Name " + attInfo.getFileName());
System.out.println("Size " + attInfo.getFileSize());
}
} catch(InterruptedException | BulkOperationException | ExecutionException ex) {
System.out.println(ex.getMessage());
}
Rich Text
Domino and Notes use rich text fields to store a variety of objects, including text, tables, document links, bitmaps, and OLE links. Rich text fields have several advantages over other types of fields:
- Paragraphs in rich text can have mixed attributes, such as indenting, justification, and spacing.
- Text in rich text can have mixed attributes such as font face, color, and point size.
- A single rich text field can hold several megabytes of data.
The com.hcl.domino.db API for reading and writing rich text to and from documents treats rich text data as a stream. Since rich text data can exceed the maximum size of a single Notes item, multiple items of the same name may be used to represent rich text data. The com.hcl.domino.db API will concatenate rich text data from multiple items with the same name into a single stream. The data type word at the beginning of every Notes item is never included in the stream. The data format is the canonical CD record format (little endian byte ordering and byte aligned data structures). Strings are formatted in the Lotus Multibyte Character Set format (also known as LMBCS).
Rich Text Fields
Since rich text data can span multiple document items, we define a rich text field as one or more Notes items of the same name that contain rich text data.
Font Table
A font table is necessary when a rich text field in a document contains text
that uses font faces other than the standard ones (Times Roman, Helvetica, and
Courier). A font table is a special item named $Fonts
formatted as rich text that
associates a font ID with a platform-independent description of the font. When
moving rich text data from one document to another, be sure to include the font table
so that the rendering program (i.e. the Notes client) can properly render the
referenced fonts.
Reading Rich Text with Java component
All of the functions that read rich text: Database::getReadRichTextMgrByUnid() and Database::getReadRichTextMgr() return a ReadRichTextMgr object which will provide the requested RichText fields wrapped in InputStream objects. Use InputsStream interfaces to read the contents of individual RichText fileds as shown in following sample code
try {
ReadRichTextMgr readManager = client.getReadRichTextMgrByUnid(unidSet,
Sets.newHashSet("Body"), null );
File file = null;
String title = "FiveBodyItems";
FileChannel wChannel = null;
InputStream richTextInputStream = readManager.readField();
if (null == richTextInputStream) {
System.err.println("No such documents found");
}
while (null != richTextInputStream) {
RichTextInputStream inputStream = (RichTextInputStream)richTextInputStream;
String fileName = inputStream.getFieldName(); //
file = new File(fileName);
try {
wChannel = new FileOutputStream(file, true).getChannel();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read;
byte[] data = new byte[40*1024];
while (richTextInputStream.available()!=0) {
read = richTextInputStream.read(data);
wChannel.write(ByteBuffer.wrap(data, 0, read));
}
wChannel.close();
richTextInputStream.close();
}
}catch (IOException | DocumentException | InterruptedException ex) {
ex.printStackTrace();
}
Writing Rich Text with Java component
Rich text can be written to a document using the com.hcl.domino.db API provided it is formatted as Notes canonical composite data record format. Note that records must start on an even-byte boundary. So when writing data, pad odd-length records with a 0 byte, without changing the length value in the header. If you are using output from one of the domino-db rich text functions Database::getReadRichTextMgrByUnid() or Database::getReadRichTextMgr() this padding is done automatically.
Use Database::getWriteRichTextMgr({})
to create a WriteRichTextMgr that
is used to write data to one or more documents.
Following is an example that creates a document and writes a rich text field to
it using rich text data received from
Database::bulkReadRichTextStream().
This excerpt assumes the caller has an instance to a Database object
that references the node-demo.nsf database included with the AppDev pack:
Database client = server.useDatabase(TARGET_DATABASE);
List<Item<?>> itemList = new ArrayList<Item<?>>();
itemList.add(new TextItem("Form", "RichDiscussion"));
itemList.add(new TextItem("Title", "WriteSimple"));
String rtFile = "fivebody.bin";
InputStream inputStream = new FileInputStream(rtFile);
long fileSize = new File(rtFile).length();
byte[] allBytes = new byte[(int) fileSize];
inputStream.read(allBytes);
ByteBuffer fieldData = ByteBuffer.wrap(allBytes);
Document responseDoc =
client.createDocument(new Document(itemList)).get();
unidSet.clear();
unidSet.add(responseDoc.getUnid());
WriteRichTextMgr rtWriteMgr = client.getWriteRichTextMgr();
OutputStream ostream = rtWriteMgr.addField(responseDoc.getUnid(), "Body", new OptionalChunkSizeKb(16));
byte[] b = new byte[1025];
int tempFilesize = (int)fieldData.limit();
while (tempFilesize > 0) {
int minBytes = Math.min(1025, tempFilesize);
fieldData.get(b, 0, minBytes);
ostream.write(b,0,minBytes);
tempFilesize -= minBytes;
}
ostream.close();