Saturday, November 2, 2013

Uploading a File into eDOCS DM

Once a document profile is created, a file can be uploaded to DM. On the one hand, it's simple - open a stream and upload the content.


On the other hand, this part of code is very critical, and one must be very focused on implementing it correctly with error checks. If you are like me have been supporting Hummingbird / OpenText DM for a while, you are probably aware about old bugs in DM with the common symptom - "zero-file size": A document seems to be uploaded correctly, but it's size is zero, and a user learns about this only when she tries to get her document back. I have my own theory why this problem reappears every now and then. If you are not interested to know my theory - no problem, just scroll down to the code :)

Theory

DM API is relatively low-level set of objects and functions. Anyone who uses it (let's not forget OpenText developers who have to implement Office Add-ins for every Office application) has to write quite a bit amount of code, a big deal of which is validity checking for the result and error handling. If one doesn't properly check the result of an API function call, usually he never knows if it has failed. I saw many different implementations of content uploading, but most of them were either cumbersome or had bugs.
[end of theory]

DM API provides a special class for content upload (and a similar class for download) - PCDPutStream. Getting an instance of this class is a different story, but once you get it, use its Write() method to upload chunks of data and call SetComplete() when done. Don't forget to check the result and ErrNumber:
public void UploadContent(Stream sourceStream, PCDPutStream pcdStream) {
    const int ChunkSize = 64 * 1024;

    int writtenCount;
    byte[] data = new byte[ChunkSize];
    
    using(var br = new BinaryReader(sourceStream)) {
        while(true) {
            int readCount = br.Read(data, 0, ChunkSize);
            if(readCount == 0) break;
            pcdStream.Write(data, readCount, out writtenCount);
            if(writtenCount != readCount)
                throw new DMApiException(string.Format(
                    "PCDPutStream.Write failed: {0} bytes have been written out of {1}", 
                    writtenCount, readCount));
        }
    }
    int result = pcdStream.SetComplete();
    if(result != S_OK || pcdStream.ErrNumber != 0)
        throw new DMApiException(string.Format(
            "PCDPutStream.SetComplete failed with error {0}: {1}", 
             pcdStream.ErrNumber, pcdStream.ErrDescription));
}

Get full source code of DMApiHelpers from GitHub (does this sound like an ad? :) I hope, it doesn't :)):
https://github.com/dotnetnick/edocs

No comments:

Post a Comment