]> source.dussan.org Git - poi.git/commitdiff
Add support for ExHyperlink and ExHyperlinkAtom
authorNick Burch <nick@apache.org>
Wed, 17 Jan 2007 16:59:45 +0000 (16:59 +0000)
committerNick Burch <nick@apache.org>
Wed, 17 Jan 2007 16:59:45 +0000 (16:59 +0000)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@497079 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlinkAtom.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfo.java
src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
src/scratchpad/testcases/org/apache/poi/hslf/data/WithLinks.ppt
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlinkAtom.java [new file with mode: 0644]

diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java
new file mode 100644 (file)
index 0000000..b27a396
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+* 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;
+
+/**
+ * This class represents the data of a link in the document. 
+ * @author Nick Burch
+ */
+public class ExHyperlink extends RecordContainer {
+       private byte[] _header;
+       private static long _type = 4055;
+       
+       // Links to our more interesting children
+       private ExHyperlinkAtom linkAtom;
+       private CString linkDetailsA;
+       private CString linkDetailsB;
+       private Comment2000Atom commentAtom; 
+       
+       /** 
+        * Returns the ExHyperlinkAtom of this link
+        */ 
+       public ExHyperlinkAtom getExHyperlinkAtom() { return linkAtom; }
+       
+       /**
+        * Returns the URL of the link.
+        * TODO: Figure out which of detailsA or detailsB is the
+        *  one that always holds it 
+        */
+       public String getLinkURL() {
+               return linkDetailsA.getText();
+       }
+       
+       /**
+        * Sets the URL of the link
+        * TODO: Figure out if we should always set both
+        */
+       public void setLinkURL(String url) {
+               linkDetailsA.setText(url);
+               linkDetailsB.setText(url);
+       }
+       
+       /**
+        * Get the link details (field A)
+        */
+       public String _getDetailsA() {
+               return linkDetailsA.getText();
+       }
+       /**
+        * Get the link details (field B)
+        */
+       public String _getDetailsB() {
+               return linkDetailsB.getText();
+       }
+
+       /** 
+        * Set things up, and find our more interesting children
+        */
+       protected ExHyperlink(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 ExHyperlinkAtom
+               if(_children[0] instanceof ExHyperlinkAtom) {
+                       linkAtom = (ExHyperlinkAtom)_children[0];
+               } else {
+                       throw new IllegalStateException("First child record wasn't a ExHyperlinkAtom, was of type " + _children[0].getRecordType());
+               }
+               
+               // Second child should be the first link details
+               if(_children[1] instanceof CString) {
+                       linkDetailsA = (CString)_children[1];
+               } else {
+                       throw new IllegalStateException("Second child record wasn't a CString, was of type " + _children[1].getRecordType());
+               }
+               // Third child should be the second link details
+               if(_children[2] instanceof CString) {
+                       linkDetailsB = (CString)_children[2];
+               } else {
+                       throw new IllegalStateException("Third child record wasn't a CString, was of type " + _children[2].getRecordType());
+               }
+       }
+       
+       /**
+        * Create a new ExHyperlink, with blank fields
+        */
+       public ExHyperlink() {
+               _header = new byte[8];
+               _children = new Record[3];
+               
+               // Setup our header block
+               _header[0] = 0x0f; // We are a container record
+               LittleEndian.putShort(_header, 2, (short)_type);
+               
+               // Setup our child records
+               CString csa = new CString();
+               CString csb = new CString();
+               csa.setCount(0x00);
+               csb.setCount(0x10);
+               _children[0] = new ExHyperlinkAtom();
+               _children[1] = csa;
+               _children[2] = csb;
+               findInterestingChildren();
+       }
+
+       /**
+        * We are of type 4055
+        */
+       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/ExHyperlinkAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlinkAtom.java
new file mode 100644 (file)
index 0000000..14c3707
--- /dev/null
@@ -0,0 +1,117 @@
+/* ====================================================================
+   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.Date;
+
+import org.apache.poi.hslf.util.SystemTimeUtils;
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Tne atom that holds metadata on a specific Link in the document.
+ * (The actual link is held in a sibling CString record)
+ *
+ * @author Nick Burch
+ */
+
+public class ExHyperlinkAtom extends RecordAtom
+{
+    /**
+     * Record header.
+     */
+    private byte[] _header;
+
+    /**
+     * Record data.
+     */
+    private byte[] _data;
+
+    /**
+     * Constructs a brand new link related atom record.
+     */
+    protected ExHyperlinkAtom() {
+        _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 ExHyperlinkAtom(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 ExHyperlinkAtom must be at least 4 bytes, but was only " + _data.length);
+        }
+    }
+
+    /**
+     * Gets the link number. This will match the one in the
+     *  InteractiveInfoAtom which uses the link.
+     * @return the link number
+     */
+    public int getNumber() {
+        return LittleEndian.getInt(_data,0);
+    }
+
+    /**
+     * Sets the link number
+     * @param number the link number.
+     */
+    public void setNumber(int number) {
+        LittleEndian.putInt(_data,0,number);
+    }
+    
+    /**
+     * Gets the record type.
+     * @return the record type.
+     */
+    public long getRecordType() { return RecordTypes.ExHyperlinkAtom.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);
+    }
+}
index 69ea76d302ee786cd0cb09b94aa6dbcc4e546671..f51d20ae5d4a5107abcfe3ec336015bd8f001d78 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.poi.util.LittleEndian;
  */
 public class InteractiveInfo extends RecordContainer {
        private byte[] _header;
-       private static long _type = RecordTypes.InteractiveInfo.typeID;
+       private static long _type = 4082;
        
        // Links to our more interesting children
        private InteractiveInfoAtom infoAtom;
index 499f7bf0d480566db3da8be2643bd461063e6554..e2194ab7bc559548e85e5ff985c1850f075b02ed 100644 (file)
@@ -107,8 +107,8 @@ public class RecordTypes {
     public static final Type BookmarkEntityAtom = new Type(4048,null);
     public static final Type ExLinkAtom = new Type(4049,null);
     public static final Type SrKinsokuAtom = new Type(4050,null);
-    public static final Type ExHyperlinkAtom = new Type(4051,null);
-    public static final Type ExHyperlink = new Type(4055,null);
+    public static final Type ExHyperlinkAtom = new Type(4051,ExHyperlinkAtom.class);
+    public static final Type ExHyperlink = new Type(4055,ExHyperlink.class);
     public static final Type SlideNumberMCAtom = new Type(4056,null);
     public static final Type HeadersFooters = new Type(4057,null);
     public static final Type HeadersFootersAtom = new Type(4058,null);
index 6c4a8fdd58be661c11762c198e125aaf5f5f39a8..f08a81a09b78855b92cfceb0fe16f173a3c3820d 100644 (file)
Binary files a/src/scratchpad/testcases/org/apache/poi/hslf/data/WithLinks.ppt and b/src/scratchpad/testcases/org/apache/poi/hslf/data/WithLinks.ppt differ
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlink.java
new file mode 100644 (file)
index 0000000..64a5dd3
--- /dev/null
@@ -0,0 +1,100 @@
+
+/* ====================================================================
+   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 junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Tests that ExHyperlink works properly.
+ *
+ * @author Nick Burch (nick at torchbox dot com)
+ */
+public class TestExHyperlink extends TestCase {
+       // From a real file
+       private byte[] data_a = new byte[] {
+               0x0F, 00, 0xD7-256, 0x0F, 0xA8-256, 00, 00, 00,
+               
+               00, 00, 0xD3-256, 0x0F, 04, 00, 00, 00, 
+               03, 00, 00, 00,
+               
+               00, 00, 0xBA-256, 0x0F, 0x46, 00, 00, 00, 
+               0x68, 00, 0x74, 00, 0x74, 00, 0x70, 00,
+               0x3A, 00, 0x2F, 00, 0x2F, 00, 0x6A, 00, 
+               0x61, 00, 0x6B, 00, 0x61, 00, 0x72, 00,
+               0x74, 00, 0x61, 00, 0x2E, 00, 0x61, 00,
+               0x70, 00, 0x61, 00, 0x63, 00, 0x68, 00,
+               0x65, 00, 0x2E, 00, 0x6F, 00, 0x72, 00,
+               0x67, 00, 0x2F, 00, 0x70, 00, 0x6F, 00,
+               0x69, 00, 0x2F, 00, 0x68, 00, 0x73, 00, 
+               0x73, 00, 0x66, 00, 0x2F, 00, 
+               
+               0x10, 00, 0xBA-256, 0x0F, 0x46, 00, 00, 00,
+               0x68, 00, 0x74, 00, 0x74, 00, 0x70, 00,
+               0x3A, 00, 0x2F, 00, 0x2F, 00, 0x6A, 00, 
+               0x61, 00, 0x6B, 00, 0x61, 00, 0x72, 00,
+               0x74, 00, 0x61, 00, 0x2E, 00, 0x61, 00,
+               0x70, 00, 0x61, 00, 0x63, 00, 0x68, 00,
+               0x65, 00, 0x2E, 00, 0x6F, 00, 0x72, 00,
+               0x67, 00, 0x2F, 00, 0x70, 00, 0x6F, 00,
+               0x69, 00, 0x2F, 00, 0x68, 00, 0x73, 00, 
+               0x73, 00, 0x66, 00, 0x2F, 00 
+       };
+       
+    public void testRecordType() throws Exception {
+       ExHyperlink eh = new ExHyperlink(data_a, 0, data_a.length);
+               assertEquals(4055l, eh.getRecordType());
+       }
+    
+    public void testNumber() throws Exception {
+       ExHyperlink eh = new ExHyperlink(data_a, 0, data_a.length);
+               assertEquals(3, eh.getExHyperlinkAtom().getNumber());
+    }
+    
+       public void testLinkURL() throws Exception {
+       ExHyperlink eh = new ExHyperlink(data_a, 0, data_a.length);
+       assertEquals("http://jakarta.apache.org/poi/hssf/", eh.getLinkURL());
+       }
+       public void testDetails() throws Exception {
+       ExHyperlink eh = new ExHyperlink(data_a, 0, data_a.length);
+       assertEquals("http://jakarta.apache.org/poi/hssf/", eh._getDetailsA());
+       assertEquals("http://jakarta.apache.org/poi/hssf/", eh._getDetailsB());
+       }
+
+       public void testWrite() throws Exception {
+       ExHyperlink eh = new ExHyperlink(data_a, 0, data_a.length);
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               eh.writeOut(baos);
+               byte[] b = baos.toByteArray();
+
+               assertEquals(data_a.length, b.length);
+               for(int i=0; i<data_a.length; i++) {
+                       assertEquals(data_a[i],b[i]);
+               }
+       }
+       
+       public void testRealFile() throws Exception {
+               // TODO
+       }
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlinkAtom.java b/src/scratchpad/testcases/org/apache/poi/hslf/record/TestExHyperlinkAtom.java
new file mode 100644 (file)
index 0000000..524416b
--- /dev/null
@@ -0,0 +1,106 @@
+
+/* ====================================================================
+   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 junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Tests that InteractiveInfoAtom works properly.
+ *
+ * @author Nick Burch (nick at torchbox dot com)
+ */
+public class TestExHyperlinkAtom extends TestCase {
+       // From a real file
+       private byte[] data_a = new byte[] {
+               00, 00, 0xD3-256, 0x0F, 04, 00, 00, 00,
+               01, 00, 00, 00
+       };
+       private byte[] data_b = new byte[] { 
+               00, 00, 0xD3-256, 0x0F, 04, 00, 00, 00,
+               04, 00, 00, 00
+       };
+       
+    public void testRecordType() throws Exception {
+       ExHyperlinkAtom eha = new ExHyperlinkAtom(data_a, 0, data_a.length);
+               assertEquals(4051l, eha.getRecordType());
+       }
+    
+    public void testGetNumber() throws Exception {
+       ExHyperlinkAtom eha = new ExHyperlinkAtom(data_a, 0, data_a.length);
+       ExHyperlinkAtom ehb = new ExHyperlinkAtom(data_b, 0, data_b.length);
+               
+               assertEquals(1, eha.getNumber());
+               assertEquals(4, ehb.getNumber());
+    }
+    
+       public void testWrite() throws Exception {
+       ExHyperlinkAtom eha = new ExHyperlinkAtom(data_a, 0, data_a.length);
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               eha.writeOut(baos);
+               byte[] b = baos.toByteArray();
+
+               assertEquals(data_a.length, b.length);
+               for(int i=0; i<data_a.length; i++) {
+                       assertEquals(data_a[i],b[i]);
+               }
+       }
+
+       // Create A from scratch
+    public void testCreate() throws Exception {
+       ExHyperlinkAtom eha = new ExHyperlinkAtom();
+       
+       // Set value
+       eha.setNumber(1);
+       
+               // Check it's now the same as a
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               eha.writeOut(baos);
+               byte[] b = baos.toByteArray();
+               
+               assertEquals(data_a.length, b.length);
+               for(int i=0; i<data_a.length; i++) {
+                       assertEquals(data_a[i],b[i]);
+               }
+    }
+
+       // Try to turn a into b
+       public void testChange() throws Exception {
+       ExHyperlinkAtom eha = new ExHyperlinkAtom(data_a, 0, data_a.length);
+
+               // Change the number
+               eha.setNumber(4);
+               
+               // Check bytes are now the same
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               eha.writeOut(baos);
+               byte[] b = baos.toByteArray();
+               
+               // Should now be the same
+               assertEquals(data_b.length, b.length);
+               for(int i=0; i<data_b.length; i++) {
+                       assertEquals(data_b[i],b[i]);
+               }
+       }
+}