Object embedding & linking (OLE)

ForumTopicsPostsLast post
MicroSoft Word 2007 default saving in docx format:

http://msdn2.microsoft.com/en-us/library/bb266220.aspx



Working on a kludgy solution for sites with mixed MicroSoft Office versions. If it might be useful, please provide feedback. forum -March 2008


Looks like it's going to be a problem for sites with mixed MicroSoft Office versions. When Portal/J executes on a PC with MicroSoft Word 2007, new embedded objects appear to be saved in docx format wrapped in an OLE. TIDOBLOK.OLE_OBJECT_CLASS = Word.Document.12. TIDBLOB.OLE_OBJECT_TYPE = b.

Side note: Word 2007 files are saved in "MicroSoft Open Office XML Format" with file extension docx. They can be renamed by adding extension ".zip" and WinZip can be used to see their content.

The PassPort object (contents of TIDBLOB) can be read out of the database and into a file (use OleTypeBRead.java with a minor modification).

There are a couple of things that can be done with the file.

1. Rename the file with extension ".docx" and Word 2007 complains, but will open it. Word 2007 is probably complaining about the OLE definition which it seems to ignore.

2. Open the file with a hex editor like UltraEdit. Delete all data:

a) before "PK" (zip file magic number) following a bunch of xFF's or x00's.

b) after the last occurence of "PK" plus 20 bytes.

Save the file and rename the file with extension ".docx". It is now a Word 2007 file.


For Portal/J 10.0.3 and 10.0.7, there does not appear to be any way that a previous version of MicroSoft Office can open embedded objects created by Office 2007. Even with the Compatibility Pack installed and user prompt "Convert file from" containing "Word 2007", it fails with Word popping message: "There was an error opening the file." and Portal/J hangs.

It appears MicroSoft's intent is that older versions of Word will be forward compatible with Word 2007. This forward compatibility works when Word 2007 creates a document and an older version opens the ".docx" file with Word prompting with a drop down list of formats including Word 2007. PassPort not involved.

When PassPort is involved, that is Word invoked by Portal/J is attempting to open an embedded object, the older versions of Word, even with "Word 2007" being a valid possible format, cannot open a Word 2007 object. The most likely problem is the MicroSoft compatibility pack cannot be correctly invoked. The good news is that Word 2007 embedded objects can be opened by Portal/J version 10.0.3 when it is executing on a PC with Word 2007.


A possible solution is to use Portal/J settings to force embedded documents into OLE format (as opposed to "docx" and "xlsx") in the Portal/J Administration, Configure Passport Regions, Edit Server Definitions (can also do Global), select the server, Define Param...
Application Name: RichText, Parameter Value: Word.Document.8.
Application Name: SpreadSheet, Parameter Value: Excell.Sheet.8.

Pro: Consistent embedded objects as OLEs. Mixed MicroSoft Office's on client machines will work.

Con: Users cannot use new Office 2007 features. They are warned upon saving their document that features will be lost.

Linked Word 2007 objects work. TIDOBLOK.OLE_OBJECT_CLASS = Word.Document.12. TIDBLOB.OLE_OBJECT_TYPE = b. TIDBLOB.OLE_OBJECT_BLOB is an OLE link.

Side Note: An OLE icon on a PassPort panel is used for one document type (word processor, spreadsheet, others) and is defined within the panel sym and changed via Analyst Work Bench.
11by webmaster
As far as embedded objects have been picked apart the following seems to hold true.

1. Text (TIDBLOB.Ole_Object_Type='T'). When created within PassPort, always paired with a Compressed. Can be created outside of PassPort and PassPort will create the Compressed when the OLE is accessed.

Java code attached: OleTypeTRead.java, OleTypeTWrite.java

2. Compressed (TIDBLOB.Ole_Object_Type='b'). Lempel-Ziv-Welch algorithm with the magic number, leading 2 bytes, removed. The third byte denotes the "bits per code" and is 12, i.e., x8C (9 is x89, 10 is x8A, etc) for Asset Suite / PassPort for all installations that I've seen.

Java code OleTypeBRead.java with a little modification will work. I should have written it with a parameter, I know, I know.
Following URL is a great reference for a Java implementation of the LZW algorithm for uncompressing. The code needs a little modification. Specifically remove the reading in and checking of the magic number (1st 2 bytes) in method parse_header.

http://www.unidata.ucar.edu/support/help/MailArchives/netcdf/msg03482.html


Another method of uncompressing the data after it has been read out of TIDBLOB and written to a file is to a) use a hex editor like UltraEdit (Edit, Hex Functions, Hex Insert) and add 2 bytes with the values of 0x1F and 0x9D to the beginning of the file, b) use Unix uncompress. You might have to suffix the file name with ".Z". I've tried this on Solaris and Linux with success.

3. Uncompressed (TIDBLOB.Ole_Object_Type='B').

Java code attached: OleTypeBRead.java, OleTypeBWrite.java

4. Package (TIDBLOB.Ole_Object_type='b' and TIDOBLOK.Ole_Object_Class='Package'). Used for linked OLEs.

When working with OLE's it's necessary to think in terms of a stream of bytes. An excellent source of information is the Apache project's Jakarta, component codec. The following URL is right into the heart of the matter.

http://svn.apache.org/viewvc/jakarta/commons/proper/codec/trunk/src/java/org/apache/commons/codec/binary/Hex.java?revision=480406&view=markup




For PassPort to open the OLE, the OLE's TIDOBLOK.Ole_Object_Class must be an entry in the MS Windows registry on the PC accessing PassPort via Portal/J. Access the registry via the Windows command prompt (DOS prompt) and the regedit command. Ole_Object_Class must exist under HKEY_CLASSES_ROOT. The entry must have a key of CLSID and there has to be a value in the Data identifying an existing application registered to MS Windows. "Word.Document" and "ExcelWorksheet" are pretty standard (Portal/J expects them to exist) and are a good place to start.

I'm not positive about this... before creating hex encoded data utilizing the Apache codec (aka Compression Decompression) and writing it into an EBCDIC database (DB2), the ASCII values have to be translated to EBCDIC. When reading from an EBCDIC database, the hex encoded data is changed to decimal by using the Apache codec decodeHex and then translated to ASCII.
811by webmaster
Be aware when using linked objects that logical drive names are saved as logical drive names and not Universal Naming Convention (UNC). What it means is that if user #1 has W mapped to \\server1\docs and links an OLE to W:\important.doc, user #2 with W mapped to \\server1\otherdir will not be able to access important.doc through the OLE.

Ventyx should create a preference driven option of saving linked OLEs by their UNC, unmapping logical drives if necessary.

Linked OLEs are usually Packages of type little b.
12by Anonymous
933by Anonymous
Reading TIDBLOB entries where OLE type is T.
Very informative posting at:

http://www.experts-exchange.com/Databases/Oracle/Product_Info/Q_20673467.html

00n/a
Extract PO attachments that would be included in eCommerce transactions. These include P312 block 3 Standards and Procedures with the proper Print values and Text indicated and P321 block 1 Additional Description, P321 block 3 S&P with proper Print values and Text indicated.
11by webmaster
1. Within PassPort create a new Standard & Procedure. Use the following SQL to find the OLE ID:
select * from tidoblok
order by time_stamp desc

2. Use OleTypeBWrite to create a new TIDBLOB entry, for example an Excel Spreadsheet.

3. Create a new TIDOBLOK entry for the new S&P using SQL modeled on the following:

insert into tidoblok (
ole_object_id
,ole_object_len
,ole_object_class
,ole_object_owner
,ole_object_status
,last_updated_by
,last_updated_date
,time_stamp)
values (
'OLE ID used for OleTypeBWrite'
,0
,'Excel.Sheet'
,'PassPort ID'
,'U'
,'PassPort ID'
,'20060101'
,'2006-01-01-00.00.00.000000');

4. Update the S&P with the OLE ID used for OleTypeBWrite:
update tidspmst
set ole_object_id = 'OLEID used for OleTypeBWrite'
where ole_object_id = 'original OLE ID';

5. Clean up.
delete from tidblob where ole_object_id = 'original OLE ID';
delete from tidoblok where ole_object_id = 'original OLE ID';

6. Accessing and updating the S&P via PassPort saves the OLE back as Tidblob.Ole_Object_Type's = T & B.
Tidoblok.Ole_Object_Class does not change.
12by Anonymous
Ole_Object_Id is a random number (as much as random numbers can reasonably be random). It can be populated with any 12 character string as long as it is unique.
00n/a