You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2013/12/26 01:46:17 UTC

svn commit: r1553435 - in /poi: site/src/documentation/content/xdocs/ trunk/src/java/org/apache/poi/hpsf/ trunk/src/scratchpad/src/org/apache/poi/hslf/model/ trunk/src/scratchpad/src/org/apache/poi/hslf/record/ trunk/src/scratchpad/src/org/apache/poi/h...

Author: kiwiwings
Date: Thu Dec 26 00:46:16 2013
New Revision: 1553435

URL: http://svn.apache.org/r1553435
Log:
Bug 55579 - [PATCH] Patch for add/embed OLE objects into HSLF

Modified:
    poi/site/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hpsf/ClassID.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java

Modified: poi/site/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1553435&r1=1553434&r2=1553435&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Thu Dec 26 00:46:16 2013
@@ -20,6 +20,7 @@
 <status>
     <developers>
         <!-- in strict alphabetical order -->
+        <person id="AB" name="Andreas Beeker" email="kiwiwings@apache.org"/>
         <person id="AO" name="Andrew C. Oliver" email="acoliver2@users.sourceforge.net"/>
         <person id="DS" name="Dominik Stadler" email="centic@apache.org"/>
         <person id="GJS" name="Glen Stampoultzis" email="user@poi.apache.org"/>
@@ -35,6 +36,8 @@
 
     <changes>
         <release version="3.10-beta3" date="2013-10-??">
+          <action dev="poi-developers" type="add">55579 - Support embedding OLE objects into HSLF</action>
+          <action dev="poi-developers" type="add">55818 - Add encryption support</action>
           <action dev="poi-developers" type="fix">55901 - Avoid using RMI based exception from PropertySetFactory, as it's not needed nor helpful</action>
           <action dev="poi-developers" type="fix">55850 - Fix NullPointerException during Xml-extraction from xslx</action>
           <action dev="poi-developers" type="fix">55640 - Avoid IndexOutOfboundsException when setting nested row grouping</action>

Modified: poi/trunk/src/java/org/apache/poi/hpsf/ClassID.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hpsf/ClassID.java?rev=1553435&r1=1553434&r2=1553435&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hpsf/ClassID.java (original)
+++ poi/trunk/src/java/org/apache/poi/hpsf/ClassID.java Thu Dec 26 00:46:16 2013
@@ -34,6 +34,12 @@ public class ClassID
     public static final ClassID PPT_SHOW = new ClassID("{64818D10-4F9B-11CF-86EA-00AA00B929E8}");
     public static final ClassID XLS_WORKBOOK = new ClassID("{00020841-0000-0000-C000-000000000046}");
     public static final ClassID TXT_ONLY = new ClassID("{5e941d80-bf96-11cd-b579-08002b30bfeb}"); // ???
+    public static final ClassID EXCEL97      = new ClassID("{00020820-0000-0000-C000-000000000046}");
+    public static final ClassID EXCEL95      = new ClassID("{00020810-0000-0000-C000-000000000046}");
+    public static final ClassID WORD97       = new ClassID("{00020906-0000-0000-C000-000000000046}");
+    public static final ClassID WORD95       = new ClassID("{00020900-0000-0000-C000-000000000046}");
+    public static final ClassID POWERPOINT97 = new ClassID("{64818D10-4F9B-11CF-86EA-00AA00B929E8}");
+    public static final ClassID POWERPOINT95 = new ClassID("{EA7BAE70-FB3B-11CD-A903-00AA00510EA3}");
 	
 	
     /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java?rev=1553435&r1=1553434&r2=1553435&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/OLEShape.java Thu Dec 26 00:46:16 2013
@@ -23,6 +23,8 @@ import org.apache.poi.hslf.usermodel.Obj
 import org.apache.poi.hslf.record.ExObjList;
 import org.apache.poi.hslf.record.Record;
 import org.apache.poi.hslf.record.ExEmbed;
+import org.apache.poi.hslf.record.RecordTypes;
+import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogger;
 
 
@@ -74,6 +76,42 @@ public final class OLEShape extends Pict
     }
 
     /**
+     * Set the unique identifier for the OLE object and
+     * register it in the necessary structures
+     * 
+     * @param objectId the unique identifier for the OLE object
+     */
+    public void setObjectID(int objectId){
+    	setEscherProperty(EscherProperties.BLIP__PICTUREID, objectId);
+    	
+    	EscherContainerRecord ecr = getSpContainer();
+    	EscherSpRecord spRecord = ecr.getChildById(EscherSpRecord.RECORD_ID);
+        spRecord.setFlags(spRecord.getFlags()|EscherSpRecord.FLAG_OLESHAPE);
+
+        EscherContainerRecord uerCont = ecr.getChildById((short)RecordTypes.EscherClientData);
+        if (uerCont == null) {
+        	uerCont = new EscherContainerRecord();
+        	ecr.addChildRecord(uerCont);
+        }
+        uerCont.setRecordId((short)RecordTypes.EscherClientData);
+        uerCont.setVersion((short)0x000F); // yes, we are still a container ...
+
+        UnknownEscherRecord uer = uerCont.getChildById((short)RecordTypes.ExObjRefAtom.typeID);
+        if (uer == null) {
+        	uer = new UnknownEscherRecord();
+        	uerCont.addChildRecord(uer);
+        }
+        
+        byte uerData[] = new byte[12];
+        LittleEndian.putShort( uerData, 0, (short)0 ); // options = 0
+        LittleEndian.putShort( uerData, 2, (short)RecordTypes.ExObjRefAtom.typeID); // recordId
+        LittleEndian.putInt( uerData, 4, 4 ); // remaining bytes
+        LittleEndian.putInt( uerData, 8, objectId ); // the data
+        uer.fillFields(uerData, 0, null);        
+    }
+    
+    
+    /**
      * Returns unique identifier for the OLE object.
      *
      * @return the unique identifier for the OLE object

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java?rev=1553435&r1=1553434&r2=1553435&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbedAtom.java Thu Dec 26 00:46:16 2013
@@ -70,7 +70,7 @@ public class ExEmbedAtom extends RecordA
      */
     protected ExEmbedAtom() {
         _header = new byte[8];
-        _data = new byte[7];
+        _data = new byte[8];
 
         LittleEndian.putShort(_header, 2, (short)getRecordType());
         LittleEndian.putInt(_header, 4, _data.length);
@@ -94,8 +94,8 @@ public class ExEmbedAtom extends RecordA
         _data = new byte[len-8];
         System.arraycopy(source,start+8,_data,0,len-8);
 
-        // Must be at least 4 bytes long
-        if(_data.length < 7) {
+        // Must be at least 8 bytes long
+        if(_data.length < 8) {
         	throw new IllegalArgumentException("The length of the data for a ExEmbedAtom must be at least 4 bytes, but was only " + _data.length);
         }
     }
@@ -120,6 +120,10 @@ public class ExEmbedAtom extends RecordA
         return _data[4] != 0;
     }
 
+    public void setCantLockServerB(boolean cantBeLocked) {
+    	_data[4] = (byte)(cantBeLocked ? 1 : 0);
+    }
+    
     /**
      * Gets whether it is not required to send the dimensions to the embedded object.
      *

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java?rev=1553435&r1=1553434&r2=1553435&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java Thu Dec 26 00:46:16 2013
@@ -18,6 +18,7 @@
 package org.apache.poi.hslf.usermodel;
 
 import java.awt.Dimension;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -30,6 +31,7 @@ import org.apache.poi.ddf.EscherBSERecor
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherOptRecord;
 import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.hpsf.ClassID;
 import org.apache.poi.hslf.HSLFSlideShow;
 import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
 import org.apache.poi.hslf.exceptions.HSLFException;
@@ -38,6 +40,8 @@ import org.apache.poi.hslf.model.Notes;
 import org.apache.poi.hslf.model.Slide;
 import org.apache.poi.hslf.record.*;
 import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
+import org.apache.poi.poifs.filesystem.DirectoryNode;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -723,53 +727,10 @@ public final class SlideShow {
 
 		// Add the core records for this new Slide to the record tree
 		org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
-		int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord);
-		_records = _hslfSlideShow.getRecords();
-
-		// Add the new Slide into the PersistPtr stuff
-		int offset = 0;
-		int slideOffset = 0;
-		PersistPtrHolder ptr = null;
-		UserEditAtom usr = null;
-		for (int i = 0; i < _records.length; i++) {
-			Record record = _records[i];
-			ByteArrayOutputStream out = new ByteArrayOutputStream();
-			try {
-				record.writeOut(out);
-			} catch (IOException e) {
-				throw new HSLFException(e);
-			}
-
-			// Grab interesting records as they come past
-			if (_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID) {
-				ptr = (PersistPtrHolder) _records[i];
-			}
-			if (_records[i].getRecordType() == RecordTypes.UserEditAtom.typeID) {
-				usr = (UserEditAtom) _records[i];
-			}
-
-			if (i == slideRecordPos) {
-				slideOffset = offset;
-			}
-			offset += out.size();
-		}
-
-		// persist ID is UserEditAtom.maxPersistWritten + 1
-		int psrId = usr.getMaxPersistWritten() + 1;
+		int psrId = addPersistentObject(slideRecord);
 		sp.setRefID(psrId);
 		slideRecord.setSheetId(psrId);
-
-		// Last view is now of the slide
-		usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW);
-		usr.setMaxPersistWritten(psrId); // increment the number of persit
-										 // objects
-
-		// Add the new slide into the last PersistPtr
-		// (Also need to tell it where it is)
-		slideRecord.setLastOnDiskOffset(slideOffset);
-		ptr.addSlideLookup(sp.getRefID(), slideOffset);
-		logger.log(POILogger.INFO, "New slide ended up at " + slideOffset);
-
+		
 		slide.setMasterSheet(_masters[0]);
 		// All done and added
 		return slide;
@@ -978,16 +939,6 @@ public final class SlideShow {
 	 * @return 0-based index of the movie
 	 */
 	public int addMovie(String path, int type) {
-		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
-		if (lst == null) {
-			lst = new ExObjList();
-			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
-		}
-
-		ExObjListAtom objAtom = lst.getExObjListAtom();
-		// increment the object ID seed
-		int objectId = (int) objAtom.getObjectIDSeed() + 1;
-		objAtom.setObjectIDSeed(objectId);
 		ExMCIMovie mci;
 		switch (type) {
 			case MovieShape.MOVIE_MPEG:
@@ -1000,11 +951,13 @@ public final class SlideShow {
 				throw new IllegalArgumentException("Unsupported Movie: " + type);
 		}
 
-		lst.appendChildRecord(mci);
 		ExVideoContainer exVideo = mci.getExVideo();
-		exVideo.getExMediaAtom().setObjectId(objectId);
 		exVideo.getExMediaAtom().setMask(0xE80000);
 		exVideo.getPathAtom().setText(path);
+
+		int objectId = addToObjListAtom(mci);
+		exVideo.getExMediaAtom().setObjectId(objectId);
+		
 		return objectId;
 	}
 
@@ -1019,27 +972,18 @@ public final class SlideShow {
 	 * @return 0-based index of the control
 	 */
 	public int addControl(String name, String progId) {
-		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
-		if (lst == null) {
-			lst = new ExObjList();
-			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
-		}
-		ExObjListAtom objAtom = lst.getExObjListAtom();
-		// increment the object ID seed
-		int objectId = (int) objAtom.getObjectIDSeed() + 1;
-		objAtom.setObjectIDSeed(objectId);
 		ExControl ctrl = new ExControl();
+		ctrl.setProgId(progId);
+		ctrl.setMenuName(name);
+		ctrl.setClipboardName(name);
+		
 		ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
-		oleObj.setObjID(objectId);
 		oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
 		oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
 		oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
-
-		ctrl.setProgId(progId);
-		ctrl.setMenuName(name);
-		ctrl.setClipboardName(name);
-		lst.addChildAfter(ctrl, objAtom);
-
+		
+		int objectId = addToObjListAtom(ctrl);
+		oleObj.setObjID(objectId);
 		return objectId;
 	}
 
@@ -1049,28 +993,166 @@ public final class SlideShow {
 	 * @return 0-based index of the hyperlink
 	 */
 	public int addHyperlink(Hyperlink link) {
-		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
-		if (lst == null) {
-			lst = new ExObjList();
-			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
-		}
-		ExObjListAtom objAtom = lst.getExObjListAtom();
-		// increment the object ID seed
-		int objectId = (int) objAtom.getObjectIDSeed() + 1;
-		objAtom.setObjectIDSeed(objectId);
-
 		ExHyperlink ctrl = new ExHyperlink();
 		ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom();
-		obj.setNumber(objectId);
         if(link.getType() == Hyperlink.LINK_SLIDENUMBER) {
             ctrl.setLinkURL(link.getAddress(), 0x30);
         } else {
             ctrl.setLinkURL(link.getAddress());
         }
 		ctrl.setLinkTitle(link.getTitle());
-		lst.addChildAfter(ctrl, objAtom);
+
+		int objectId = addToObjListAtom(ctrl);
 		link.setId(objectId);
+		obj.setNumber(objectId);
+
+		return objectId;
+	}
+
+	/**
+	 * Add a embedded object to this presentation
+	 *
+	 * @return 0-based index of the embedded object
+	 */
+	public int addEmbed(POIFSFileSystem poiData) {
+        DirectoryNode root = poiData.getRoot();
+        
+        // prepare embedded data
+        if (new ClassID().equals(root.getStorageClsid())) {
+        	// need to set class id
+	        Map<String,ClassID> olemap = getOleMap();
+	        ClassID classID = null;
+	    	for (Map.Entry<String,ClassID> entry : olemap.entrySet()) {
+	    		if (root.hasEntry(entry.getKey())) {
+	    			classID = entry.getValue();
+	    			break;
+	    		}
+	    	}
+	    	if (classID == null) {
+	    		throw new IllegalArgumentException("Unsupported embedded document");    		
+	    	}
+	    	
+	    	root.setStorageClsid(classID);
+        }
+        
+		ExEmbed exEmbed = new ExEmbed();
+        // remove unneccessary infos, so we don't need to specify the type
+        // of the ole object multiple times
+        Record children[] = exEmbed.getChildRecords();
+        exEmbed.removeChild(children[2]);
+        exEmbed.removeChild(children[3]);
+        exEmbed.removeChild(children[4]);
+
+        ExEmbedAtom eeEmbed = exEmbed.getExEmbedAtom();
+        eeEmbed.setCantLockServerB(true);
+
+        ExOleObjAtom eeAtom = exEmbed.getExOleObjAtom();
+        eeAtom.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
+        eeAtom.setType(ExOleObjAtom.TYPE_EMBEDDED);
+        // eeAtom.setSubType(ExOleObjAtom.SUBTYPE_EXCEL);
+        // should be ignored?!?, see MS-PPT ExOleObjAtom, but Libre Office sets it ...
+        eeAtom.setOptions(1226240);
+
+        ExOleObjStg exOleObjStg = new ExOleObjStg();
+        try {
+	        final String OLESTREAM_NAME = "\u0001Ole";
+	        if (!root.hasEntry(OLESTREAM_NAME)) {
+	            // the following data was taken from an example libre office document
+	            // beside this "\u0001Ole" record there were several other records, e.g. CompObj,
+	            // OlePresXXX, but it seems, that they aren't neccessary
+	            byte oleBytes[] = { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	            poiData.createDocument(new ByteArrayInputStream(oleBytes), OLESTREAM_NAME);
+	        }        
+
+	        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+	        poiData.writeFilesystem(bos);
+	        exOleObjStg.setData(bos.toByteArray());
+        } catch (IOException e) {
+        	throw new HSLFException(e);
+        }
+        
+        int psrId = addPersistentObject(exOleObjStg);
+        exOleObjStg.setPersistId(psrId);
+        eeAtom.setObjStgDataRef(psrId);
+        
+		int objectId = addToObjListAtom(exEmbed);
+		eeAtom.setObjID(objectId);
+		return objectId;
+	}
+
+	protected int addToObjListAtom(RecordContainer exObj) {
+		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
+		if (lst == null) {
+			lst = new ExObjList();
+			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
+		}
+		ExObjListAtom objAtom = lst.getExObjListAtom();
+		// increment the object ID seed
+		int objectId = (int) objAtom.getObjectIDSeed() + 1;
+		objAtom.setObjectIDSeed(objectId);
 
+		lst.addChildAfter(exObj, objAtom);
+		
 		return objectId;
 	}
+
+    protected static Map<String,ClassID> getOleMap() {
+    	Map<String,ClassID> olemap = new HashMap<String,ClassID>();
+    	olemap.put("PowerPoint Document", ClassID.PPT_SHOW);
+    	olemap.put("Workbook", ClassID.EXCEL97); // as per BIFF8 spec
+    	olemap.put("WORKBOOK", ClassID.EXCEL97); // Typically from third party programs
+    	olemap.put("BOOK", ClassID.EXCEL97); // Typically odd Crystal Reports exports
+    	// ... to be continued
+    	return olemap;
+    }
+
+    protected int addPersistentObject(PositionDependentRecord slideRecord) {
+		int slideRecordPos = _hslfSlideShow.appendRootLevelRecord((Record)slideRecord);
+		_records = _hslfSlideShow.getRecords();
+
+		// Add the new Slide into the PersistPtr stuff
+		int offset = 0;
+		int slideOffset = 0;
+		PersistPtrHolder ptr = null;
+		UserEditAtom usr = null;
+		int i = 0;
+		for (Record record : _records) {
+            // Grab interesting records as they come past
+			int recordType = (int)record.getRecordType();
+            if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) {
+                ptr = (PersistPtrHolder)record;
+            }
+            if (recordType == RecordTypes.UserEditAtom.typeID) {
+                usr = (UserEditAtom)record;
+            }
+
+			if (i++ == slideRecordPos) {
+				slideOffset = offset;
+			}
+			
+			try {
+				ByteArrayOutputStream out = new ByteArrayOutputStream();
+				record.writeOut(out);
+				offset += out.size();
+			} catch (IOException e) {
+				throw new HSLFException(e);
+			}
+		}
+
+		// persist ID is UserEditAtom.maxPersistWritten + 1
+		int psrId = usr.getMaxPersistWritten() + 1;
+
+		// Last view is now of the slide
+		usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW);
+		// increment the number of persistent objects
+		usr.setMaxPersistWritten(psrId);
+
+		// Add the new slide into the last PersistPtr
+		// (Also need to tell it where it is)
+		slideRecord.setLastOnDiskOffset(slideOffset);
+		ptr.addSlideLookup(psrId, slideOffset);
+		logger.log(POILogger.INFO, "New slide/object ended up at " + slideOffset);
+
+		return psrId;
+    }
 }

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java?rev=1553435&r1=1553434&r2=1553435&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestOleEmbedding.java Thu Dec 26 00:46:16 2013
@@ -17,8 +17,16 @@
 
 package org.apache.poi.hslf.model;
 
+import java.awt.geom.Rectangle2D;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Arrays;
+
 import junit.framework.TestCase;
 
+import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.HSLFSlideShow;
 import org.apache.poi.hslf.usermodel.ObjectData;
 import org.apache.poi.hslf.usermodel.PictureData;
@@ -26,7 +34,8 @@ import org.apache.poi.hslf.usermodel.Sli
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.hwpf.HWPFDocument;
-import org.apache.poi.POIDataSamples;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.IOUtils;
 
 public final class TestOleEmbedding extends TestCase {
     private static POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
@@ -82,4 +91,52 @@ public final class TestOleEmbedding exte
         }
         assertEquals("Expected 2 OLE shapes", 2, cnt);
     }
+    
+    public void testEmbedding() throws Exception {
+    	HSLFSlideShow _hslfSlideShow = HSLFSlideShow.create();
+    	SlideShow ppt = new SlideShow(_hslfSlideShow);
+    	
+    	File pict = POIDataSamples.getSlideShowInstance().getFile("clock.jpg");
+    	int pictId = ppt.addPicture(pict, Picture.JPEG);
+    	
+    	InputStream is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("Employee.xls");
+    	POIFSFileSystem poiData1 = new POIFSFileSystem(is);
+    	is.close();
+    	
+    	int oleObjectId1 = ppt.addEmbed(poiData1);
+    	
+    	Slide slide1 = ppt.createSlide();
+    	OLEShape oleShape1 = new OLEShape(pictId);
+    	oleShape1.setObjectID(oleObjectId1);
+    	slide1.addShape(oleShape1);
+    	oleShape1.setAnchor(new Rectangle2D.Double(100,100,100,100));
+    	
+    	// add second slide with different order in object creation
+    	Slide slide2 = ppt.createSlide();
+    	OLEShape oleShape2 = new OLEShape(pictId);
+
+        is = POIDataSamples.getSpreadSheetInstance().openResourceAsStream("SimpleWithImages.xls");
+        POIFSFileSystem poiData2 = new POIFSFileSystem(is);
+        is.close();
+    	
+        int oleObjectId2 = ppt.addEmbed(poiData2);
+
+        oleShape2.setObjectID(oleObjectId2);
+        slide2.addShape(oleShape2);
+        oleShape2.setAnchor(new Rectangle2D.Double(100,100,100,100));
+        
+    	ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    	ppt.write(bos);
+    	
+    	ppt = new SlideShow(new ByteArrayInputStream(bos.toByteArray()));
+    	OLEShape comp = (OLEShape)ppt.getSlides()[0].getShapes()[0];
+    	byte compData[] = IOUtils.toByteArray(comp.getObjectData().getData());
+    	
+    	bos.reset();
+    	poiData1.writeFilesystem(bos);
+    	byte expData[] = bos.toByteArray();
+    	
+    	assertTrue(Arrays.equals(expData, compData));
+    	
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org