diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/Document.java b/src/scratchpad/src/org/apache/poi/hslf/record/Document.java index 68424e7e4..cbbb2f90e 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/Document.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/Document.java @@ -39,6 +39,7 @@ public class Document extends PositionDependentRecordContainer private Environment environment; private PPDrawingGroup ppDrawing; private SlideListWithText[] slwts; + private ExObjList exObjList; // Can be null /** * Returns the DocumentAtom of this Document @@ -54,6 +55,12 @@ public class Document extends PositionDependentRecordContainer * that contains information on pictures in the slides. */ public PPDrawingGroup getPPDrawingGroup() { return ppDrawing; } + /** + * Returns the ExObjList, which holds the references to + * external objects used in the slides. This may be null, if + * there are no external references. + */ + public ExObjList getExObjList() { return exObjList; } /** * Returns all the SlideListWithTexts that are defined for @@ -116,6 +123,9 @@ public class Document extends PositionDependentRecordContainer if(_children[i] instanceof PPDrawingGroup) { ppDrawing = (PPDrawingGroup)_children[i]; } + if(_children[i] instanceof ExObjList) { + exObjList = (ExObjList)_children[i]; + } } // You should only every have 1, 2 or 3 SLWTs diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java new file mode 100644 index 000000000..95fe5c967 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java @@ -0,0 +1,112 @@ +/* +* 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 java.util.ArrayList; + +import org.apache.poi.util.LittleEndian; + +/** + * This class holds the links to exernal objects referenced + * from the document. + * @author Nick Burch + */ +public class ExObjList extends RecordContainer { + private byte[] _header; + private static long _type = 1033; + + // Links to our more interesting children + private ExObjListAtom exObjListAtom; + + /** + * Returns the ExObjListAtom of this list + */ + public ExObjListAtom getExObjListAtom() { return exObjListAtom; } + + /** + * Returns all the ExHyperlinks + */ + public ExHyperlink[] getExHyperlinks() { + ArrayList links = new ArrayList(); + for(int i=0; i<_children.length; i++) { + if(_children[i] instanceof ExHyperlink) { + links.add(_children[i]); + } + } + + return (ExHyperlink[])links.toArray(new ExHyperlink[links.size()]); + } + + /** + * Set things up, and find our more interesting children + */ + protected ExObjList(byte[] source, int start, int len) { + // Grab the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Find our children + _children = Record.findChildRecords(source,start+8,len-8); + findInterestingChildren(); + } + + /** + * Go through our child records, picking out the ones that are + * interesting, and saving those for use by the easy helper + * methods. + */ + private void findInterestingChildren() { + // First child should be the atom + if(_children[0] instanceof ExObjListAtom) { + exObjListAtom = (ExObjListAtom)_children[0]; + } else { + throw new IllegalStateException("First child record wasn't a ExObjListAtom, was of type " + _children[0].getRecordType()); + } + } + + /** + * Create a new ExObjList, with blank fields + */ + public ExObjList() { + _header = new byte[8]; + _children = new Record[1]; + + // Setup our header block + _header[0] = 0x0f; // We are a container record + LittleEndian.putShort(_header, 2, (short)_type); + + // Setup our child records + _children[0] = new ExObjListAtom(); + findInterestingChildren(); + } + + /** + * We are of type 1033 + */ + public long getRecordType() { return _type; } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + writeOut(_header[0],_header[1],_type,_children,out); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java new file mode 100644 index 000000000..51bb5b4ee --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExObjListAtom.java @@ -0,0 +1,114 @@ +/* ==================================================================== + 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; + +/** + * Tne atom that holds the seed info used by a ExObjList + * + * @author Nick Burch + */ + +public class ExObjListAtom extends RecordAtom +{ + /** + * Record header. + */ + private byte[] _header; + + /** + * Record data. + */ + private byte[] _data; + + /** + * Constructs a brand new link related atom record. + */ + protected ExObjListAtom() { + _header = new byte[8]; + _data = new byte[4]; + + LittleEndian.putShort(_header, 2, (short)getRecordType()); + LittleEndian.putInt(_header, 4, _data.length); + + // It is fine for the other values to be zero + } + + /** + * Constructs the link related atom 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 ExObjListAtom(byte[] source, int start, int len) { + // Get the header. + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Get the record data. + _data = new byte[len-8]; + System.arraycopy(source,start+8,_data,0,len-8); + + // Must be at least 4 bytes long + if(_data.length < 4) { + throw new IllegalArgumentException("The length of the data for a ExObjListAtom must be at least 4 bytes, but was only " + _data.length); + } + } + + /** + * Gets the object ID seed, which will be used as the unique + * OLE identifier for the next OLE object added + * @return the object ID seed + */ + public long getObjectIDSeed() { + return LittleEndian.getUInt(_data,0); + } + + /** + * Sets the object ID seed + * @param seed the new ID seed + */ + public void setObjectIDSeed(int seed) { + LittleEndian.putInt(_data,0,seed); + } + + /** + * Gets the record type. + * @return the record type. + */ + public long getRecordType() { return RecordTypes.ExObjListAtom.typeID; } + + /** + * Write the contents of the record back, so it can be written + * to disk + * + * @param out the output stream to write to. + * @throws IOException if an error occurs. + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + out.write(_data); + } +} 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 5e69dcead..3183bd553 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -59,8 +59,8 @@ public class RecordTypes { public static final Type DocRoutingSlip = new Type(1030,null); public static final Type OutlineViewInfo = new Type(1031,null); public static final Type SorterViewInfo = new Type(1032,null); - public static final Type ExObjList = new Type(1033,DummyRecordWithChildren.class); - public static final Type ExObjListAtom = new Type(1034,null); + public static final Type ExObjList = new Type(1033,ExObjList.class); + public static final Type ExObjListAtom = new Type(1034,ExObjListAtom.class); public static final Type PPDrawingGroup = new Type(1035,PPDrawingGroup.class); public static final Type PPDrawing = new Type(1036,PPDrawing.class); public static final Type NamedShows = new Type(1040,null); diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java index ad489a5d5..d559e542c 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java @@ -23,6 +23,7 @@ package org.apache.poi.hslf.record; import junit.framework.TestCase; import java.io.ByteArrayOutputStream; +import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -100,16 +101,16 @@ public class TestExHyperlink extends TestCase { public void testRealFile() throws Exception { String dirname = System.getProperty("HSLF.testdata.path"); - HSLFSlideShow hss = new HSLFSlideShow(dirname + "WithLinks.ppt"); + HSLFSlideShow hss = new HSLFSlideShow(dirname + File.separator + "WithLinks.ppt"); SlideShow ss = new SlideShow(hss); // Get the document Document doc = ss.getDocumentRecord(); // Get the ExObjList - RecordContainer exObjList = null; + ExObjList exObjList = null; for(int i=0; i