From e212f1ad6c740988c1a4f3180c6d43b833de76d9 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Wed, 14 May 2008 10:18:00 +0000 Subject: [PATCH] Support for embedded ActiveX objects: PowerPoint references them similar to embedded documents but in a different container: ExControl instead of ExEmbed git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@656215 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/hslf/examples/DataExtraction.java | 23 ++--- .../apache/poi/hslf/model/ShapeFactory.java | 1 + .../org/apache/poi/hslf/record/ExControl.java | 95 ++++++++++++++++++ .../apache/poi/hslf/record/ExControlAtom.java | 96 +++++++++++++++++++ .../org/apache/poi/hslf/record/ExEmbed.java | 20 ++-- .../apache/poi/hslf/record/ExOleObjStg.java | 15 ++- .../apache/poi/hslf/record/RecordTypes.java | 2 +- 7 files changed, 229 insertions(+), 23 deletions(-) create mode 100755 src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java create mode 100755 src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java diff --git a/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java index 05bf82472f..611466c924 100755 --- a/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java +++ b/src/scratchpad/examples/src/org/apache/poi/hslf/examples/DataExtraction.java @@ -69,16 +69,9 @@ public class DataExtraction { String name = ole.getInstanceName(); if ("Worksheet".equals(name)) { - //save xls on disk - FileOutputStream out = new FileOutputStream(name + "-("+(j)+").xls"); - InputStream dis = data.getData(); - byte[] chunk = new byte[2048]; - int count; - while ((count = dis.read(chunk)) >= 0) { - out.write(chunk,0,count); - } - is.close(); - out.close(); + //read xls + HSSFWorkbook wb = new HSSFWorkbook(data.getData()); + } else if ("Document".equals(name)) { HWPFDocument doc = new HWPFDocument(data.getData()); //read the word document @@ -93,7 +86,15 @@ public class DataExtraction { doc.write(out); out.close(); } else { - System.err.println("Processing " + name); + FileOutputStream out = new FileOutputStream(ole.getProgID() + "-"+(j+1)+".dat"); + InputStream dis = data.getData(); + byte[] chunk = new byte[2048]; + int count; + while ((count = dis.read(chunk)) >= 0) { + out.write(chunk,0,count); + } + is.close(); + out.close(); } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java index 4abc8c1c00..4bef9033db 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java +++ b/src/scratchpad/src/org/apache/poi/hslf/model/ShapeFactory.java @@ -76,6 +76,7 @@ public class ShapeFactory { case ShapeTypes.TextBox: shape = new TextBox(spContainer, parent); break; + case ShapeTypes.HostControl: case ShapeTypes.PictureFrame: { EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID); EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.BLIP__PICTUREID); diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java new file mode 100755 index 0000000000..e6e7da893c --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExControl.java @@ -0,0 +1,95 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.OutputStream; +import java.io.IOException; + +import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.POILogger; + +/** + * Container for OLE Control object. It contains: + *

+ * 1. ExControlAtom (4091) + * 2. ExOleObjAtom (4035) + * 3. CString (4026), Instance MenuName (1) used for menus and the Links dialog box. + * 4. CString (4026), Instance ProgID (2) that stores the OLE Programmatic Identifier. + * A ProgID is a string that uniquely identifies a given object. + * 5. CString (4026), Instance ClipboardName (3) that appears in the paste special dialog. + * 6. MetaFile( 4033), optional + *

+ * + * + * @author Yegor kozlov + */ +public class ExControl extends ExEmbed { + + // Links to our more interesting children + private ExControlAtom ctrlAtom; + + /** + * Set things up, and find our more interesting children + * + * @param source the source data as a byte array. + * @param start the start offset into the byte array. + * @param len the length of the slice in the byte array. + */ + protected ExControl(byte[] source, int start, int len) { + super(source, start, len); + } + + /** + * Create a new ExEmbed, with blank fields + */ + public ExControl() { + super(); + + _children[0] = ctrlAtom = new ExControlAtom(); + } + + /** + * Gets the {@link ExControlAtom}. + * + * @return the {@link ExControlAtom}. + */ + public ExControlAtom getExControlAtom() + { + return ctrlAtom; + } + + /** + * Returns the type (held as a little endian in bytes 3 and 4) + * that this class handles. + * + * @return the record type. + */ + public long getRecordType() { + return RecordTypes.ExControl.typeID; + } + + protected RecordAtom getEmbedAtom(Record[] children){ + RecordAtom atom = null; + if(_children[0] instanceof ExControlAtom) { + atom = (ExControlAtom)_children[0]; + } else { + logger.log(POILogger.ERROR, "First child record wasn't a ExControlAtom, was of type " + _children[0].getRecordType()); + } + return atom; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java new file mode 100755 index 0000000000..ae99d0a235 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExControlAtom.java @@ -0,0 +1,96 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.poi.util.LittleEndian; + +/** + * Contains a long integer, slideID, which stores the unique slide identifier of the slide + * where this control resides. + * + * @author Yegor Kozlov + */ +public class ExControlAtom extends RecordAtom { + + + /** + * Record header. + */ + private byte[] _header; + + /** + * slideId. + */ + private int _id; + + /** + * Constructs a brand new embedded object atom record. + */ + protected ExControlAtom() { + _header = new byte[8]; + + LittleEndian.putShort(_header, 2, (short) getRecordType()); + LittleEndian.putInt(_header, 4, 4); + + } + + /** + * Constructs the ExControlAtom record from its source data. + * + * @param source the source data as a byte array. + * @param start the start offset into the byte array. + * @param len the length of the slice in the byte array. + */ + protected ExControlAtom(byte[] source, int start, int len) { + // Get the header. + _header = new byte[8]; + System.arraycopy(source, start, _header, 0, 8); + + _id = LittleEndian.getInt(source, start + 8); + } + + public int getSlideId() { + return _id; + } + + /** + * Gets the record type. + * @return the record type. + */ + public long getRecordType() { + return RecordTypes.ExControlAtom.typeID; + } + + /** + * Write the contents of the record back, so it can be written + * to disk + * + * @param out the output stream to write to. + * @throws java.io.IOException if an error occurs. + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + byte[] data = new byte[4]; + LittleEndian.putInt(data, _id); + out.write(data); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java index 9e58e8ae18..501712e9d5 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExEmbed.java @@ -36,7 +36,7 @@ public class ExEmbed extends RecordContainer { private byte[] _header; // Links to our more interesting children - private ExEmbedAtom embedAtom; + private RecordAtom embedAtom; private ExOleObjAtom oleObjAtom; private CString menuName; private CString progId; @@ -91,11 +91,7 @@ public class ExEmbed extends RecordContainer { private void findInterestingChildren() { // First child should be the ExHyperlinkAtom - if(_children[0] instanceof ExEmbedAtom) { - embedAtom = (ExEmbedAtom)_children[0]; - } else { - logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType()); - } + embedAtom = getEmbedAtom(_children); // Second child should be the ExOleObjAtom if (_children[1] instanceof ExOleObjAtom) { @@ -115,6 +111,16 @@ public class ExEmbed extends RecordContainer { } } + protected RecordAtom getEmbedAtom(Record[] children){ + RecordAtom atom = null; + if(_children[0] instanceof ExEmbedAtom) { + atom = (ExEmbedAtom)_children[0]; + } else { + logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType()); + } + return atom; + } + /** * Gets the {@link ExEmbedAtom}. * @@ -122,7 +128,7 @@ public class ExEmbed extends RecordContainer { */ public ExEmbedAtom getExEmbedAtom() { - return embedAtom; + return (ExEmbedAtom)embedAtom; } /** diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java index 197497fd02..f729c2da1a 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java @@ -17,11 +17,9 @@ package org.apache.poi.hslf.record; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.util.zip.InflaterInputStream; +import java.util.zip.DeflaterOutputStream; import org.apache.poi.util.LittleEndian; @@ -92,6 +90,15 @@ public class ExOleObjStg extends RecordAtom implements PersistRecord { return new InflaterInputStream(compressedStream); } + public void setData(byte[] data) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(data.length); + DeflaterOutputStream def = new DeflaterOutputStream(out); + def.write(data, 0, data.length); + def.finish(); + _data = out.toByteArray(); + LittleEndian.putInt(_header, 4, _data.length); + } + /** * Gets the record type. * diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java index cedc99ce0a..a6f00da124 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -119,7 +119,7 @@ public class RecordTypes { public static final Type RecolorInfoAtom = new Type(4071,null); public static final Type ExQuickTimeMovie = new Type(4074,null); public static final Type ExQuickTimeMovieData = new Type(4075,null); - public static final Type ExControl = new Type(4078,null); + public static final Type ExControl = new Type(4078,ExControl.class); public static final Type SlideListWithText = new Type(4080,SlideListWithText.class); public static final Type InteractiveInfo = new Type(4082,InteractiveInfo.class); public static final Type InteractiveInfoAtom = new Type(4083,InteractiveInfoAtom.class); -- 2.39.5