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
This commit is contained in:
Yegor Kozlov 2008-05-14 10:18:00 +00:00
parent 643df24cfb
commit c0e0729da0
7 changed files with 229 additions and 23 deletions

View File

@ -69,16 +69,9 @@ public class DataExtraction {
String name = ole.getInstanceName(); String name = ole.getInstanceName();
if ("Worksheet".equals(name)) { if ("Worksheet".equals(name)) {
//save xls on disk //read xls
FileOutputStream out = new FileOutputStream(name + "-("+(j)+").xls"); HSSFWorkbook wb = new HSSFWorkbook(data.getData());
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();
} else if ("Document".equals(name)) { } else if ("Document".equals(name)) {
HWPFDocument doc = new HWPFDocument(data.getData()); HWPFDocument doc = new HWPFDocument(data.getData());
//read the word document //read the word document
@ -93,7 +86,15 @@ public class DataExtraction {
doc.write(out); doc.write(out);
out.close(); out.close();
} else { } 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();
} }
} }

View File

@ -76,6 +76,7 @@ public class ShapeFactory {
case ShapeTypes.TextBox: case ShapeTypes.TextBox:
shape = new TextBox(spContainer, parent); shape = new TextBox(spContainer, parent);
break; break;
case ShapeTypes.HostControl:
case ShapeTypes.PictureFrame: { case ShapeTypes.PictureFrame: {
EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID); EscherOptRecord opt = (EscherOptRecord)Shape.getEscherChild(spContainer, EscherOptRecord.RECORD_ID);
EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.BLIP__PICTUREID); EscherProperty prop = Shape.getEscherProperty(opt, EscherProperties.BLIP__PICTUREID);

View File

@ -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:
* <p>
* 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
* </p>
*
*
* @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;
}
}

View File

@ -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);
}
}

View File

@ -36,7 +36,7 @@ public class ExEmbed extends RecordContainer {
private byte[] _header; private byte[] _header;
// Links to our more interesting children // Links to our more interesting children
private ExEmbedAtom embedAtom; private RecordAtom embedAtom;
private ExOleObjAtom oleObjAtom; private ExOleObjAtom oleObjAtom;
private CString menuName; private CString menuName;
private CString progId; private CString progId;
@ -91,11 +91,7 @@ public class ExEmbed extends RecordContainer {
private void findInterestingChildren() { private void findInterestingChildren() {
// First child should be the ExHyperlinkAtom // First child should be the ExHyperlinkAtom
if(_children[0] instanceof ExEmbedAtom) { embedAtom = getEmbedAtom(_children);
embedAtom = (ExEmbedAtom)_children[0];
} else {
logger.log(POILogger.ERROR, "First child record wasn't a ExEmbedAtom, was of type " + _children[0].getRecordType());
}
// Second child should be the ExOleObjAtom // Second child should be the ExOleObjAtom
if (_children[1] instanceof 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}. * Gets the {@link ExEmbedAtom}.
* *
@ -122,7 +128,7 @@ public class ExEmbed extends RecordContainer {
*/ */
public ExEmbedAtom getExEmbedAtom() public ExEmbedAtom getExEmbedAtom()
{ {
return embedAtom; return (ExEmbedAtom)embedAtom;
} }
/** /**

View File

@ -17,11 +17,9 @@
package org.apache.poi.hslf.record; package org.apache.poi.hslf.record;
import java.io.ByteArrayInputStream; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.InflaterInputStream; import java.util.zip.InflaterInputStream;
import java.util.zip.DeflaterOutputStream;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
@ -92,6 +90,15 @@ public class ExOleObjStg extends RecordAtom implements PersistRecord {
return new InflaterInputStream(compressedStream); 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. * Gets the record type.
* *

View File

@ -119,7 +119,7 @@ public class RecordTypes {
public static final Type RecolorInfoAtom = new Type(4071,null); public static final Type RecolorInfoAtom = new Type(4071,null);
public static final Type ExQuickTimeMovie = new Type(4074,null); public static final Type ExQuickTimeMovie = new Type(4074,null);
public static final Type ExQuickTimeMovieData = new Type(4075,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 SlideListWithText = new Type(4080,SlideListWithText.class);
public static final Type InteractiveInfo = new Type(4082,InteractiveInfo.class); public static final Type InteractiveInfo = new Type(4082,InteractiveInfo.class);
public static final Type InteractiveInfoAtom = new Type(4083,InteractiveInfoAtom.class); public static final Type InteractiveInfoAtom = new Type(4083,InteractiveInfoAtom.class);