HendrikHoetker / OutlookItemTransfer

MIT License
2 stars 1 forks source link

OutlookItemTransfer

Motivation

There are some closed source libs on the market which are quite costly to implement Drag'n Drop from Outlook to a Java application. There are also many sources which are very incomplete or misleading in the internet.

Also a lot of statments in the internet (stackexchange.com, etc.) tell about very complicated ways including "doing it in C++ or C#", using JNI and/or writing the dragged item to a temp file and read it back again.

I wanted a small library to be used the same way as other Transfer classes in Java SWT (like FileTransfer or LocalSelectionTransfer). My target was to provide the dragged Outlook item as a an array of bytes.

Description

I provide all code required for implementing Drag'n Drop from Outlook to an Eclipse SWT application using the SWT drag'n drop processes.

Dependencies to other libraries

The implementation relies on:

Implementation

Usage

// check for outlook drop item
if (DragAndDropTransfer.get.getOutlookItemTransfer().isSupportedType(event.currentDataType)) {
    Object o = DragAndDropTransfer.get.getOutlookItemTransfer().nativeToJava(event.currentDataType);
    if (o != null && o instanceof Object[]) {
        Object[] objectArray = (Object[])o;
        for (Object objItem: objectArray) {
            if (objItem instanceof OutlookMessage) {
                OutlookMessage msg = (OutlookMessage)objItem;

                // ...
                // Filename in: msg.getFilename()
                // Binary data in: msg.getFileContents()
                // ...
            }
        }
    }
}

Validation

The implementation is validated on

OutlookItemTransfer

OutlookItemTransfer provides the Drag implementation (only dragging from Outlook, but not dropping to Outlook is implemented). The Transfer class is subclassed to Transfer, not ByteArrayTransfer. The behaviour is very similar to the ByteArrayTransfer, but it considers some small modifications compared to the ByteArrayTransfer.

The OutlookItemTransfer can be used as any other SWT Transfer class.

The method nativeToJava will return an Array of OutlookItem: OutlookItem[]. Each item represents one dragged item from Outlook.

The method javaToNative is not implemented as dropping to Outlook is not considered in my use cases.

OutlookItem

The OutlookItem is representing one single item dragged from Outlook. The OutlookItem provides

Internals

The dragged item from Outlook is provided as IStorage object. IStorage is similar to a file system directory containing further IStorage objects (sub directories) as well as IStream objects representing files.

The internal structure is called CompoundObject where an IStorage is represented by an CompoundStorage, an IStream by an CompoundStream. Hint: I added a CompoundRoot to indicate the file system's root directory. Outlook provides an IStorage as root object.

Outlook provides a virtual file system of IStorages and IStreams which are 1:1 represented in a tree of CompoundStorage and CompoundStreams.

The data of the IStream is extracted and stored at each CompoundStream object.

The .MSG file is nothing else than a binary dump of the virtual file system plus some header informations. This is the same also for other Office files (.XLS, .DOC, etc.).

The resulting virtual file system is actually written using the Apache POI library and the byte stream is extracted.

In the end the implementation could be simplified by removing the Compound* objects and directly writing the information to the Apache POI library. Intention was here to have a 1:1 representation of the dragged object in memory for further analyzes. One could use CompoundRoot.toString() to dump the initially provided IStorage data to a String.

License

All source code files are provided under MIT License, see LICENSE.md. I do not provide any warranty to the code. It is only tested under limited conditions for my own use cases.

Resources

The following resources helped me to understand the whole story. Some provide pieces of code I then use in my implementation.

Versions

Your Motivation

It would be great to have an open contribution. If you find issues and room for further improvements in my implementation please feel free to provide bug fixes or further improvements.