]> source.dussan.org Git - poi.git/commitdiff
Make a start on the hyperlink record support - not finished yet though, so not enabled
authorNick Burch <nick@apache.org>
Fri, 1 Feb 2008 15:20:55 +0000 (15:20 +0000)
committerNick Burch <nick@apache.org>
Fri, 1 Feb 2008 15:20:55 +0000 (15:20 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@617516 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/HyperlinkRecord.java [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java [new file with mode: 0644]

diff --git a/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java b/src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
new file mode 100644 (file)
index 0000000..76f9f53
--- /dev/null
@@ -0,0 +1,350 @@
+/* ====================================================================
+ Copyright 2002-2004   Apache Software Foundation
+
+ Licensed 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.
+ ==================================================================== */
+
+/*
+ * HyperlinkRecord
+ *
+ * Created on February 20th, 2005, 16:00 PM
+ */
+package org.apache.poi.hssf.record;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.LittleEndian;
+import org.apache.poi.util.StringUtil;
+
+/**The <code>HyperlinkRecord</code> wraps an HLINK-record from the Excel-97 format 
+ *
+ * @version     20-feb-2005
+ * @author      Mark Hissink Muller <a href="mailto:mark@hissinkmuller.nl >mark&064;hissinkmuller.nl</a>
+ *
+ * Version by   date     changes
+ * ------- ---  -------- -------
+ * 0.1     MHM  20022005 draft version; need to fix serialize and getRecordSize()
+ * 
+ * 1.0     MHM  20022005 (Initial version; only aims to support internet URLs (e.g. http://www.example.com) ) - added 31-08-07: AFAIK, this file is NOT functional/working. Please let me know if you turn it into something that does work.
+ */
+public class HyperlinkRecord extends Record implements CellValueRecordInterface
+{
+    /** Indicates the URL in the Record */
+    private static byte[] GUID_OF_URL_MONIKER =
+    { -32, -55, -22, 121, -7, -70, -50, 17, -116, -126, 0, -86, 0, 75, -87, 11 };
+
+    /** Indicates the STD_LINK in the Record */
+    // MHM: to be added when necessary
+    private static byte[] GUID_OF_STD_LINK =  {};
+
+    /** Logger */
+    public static final Log log = LogFactory.getLog(HyperlinkRecord.class);
+
+    // quick and dirty
+    private static final boolean _DEBUG_ = true;
+
+    public final static short sid = 0x1b8;
+
+    private int field_1_row;
+    private short field_2_column;
+    private short field_3_xf_index;
+    private short field_4_unknown;
+    private byte[] field_5_unknown;
+    private int field_6_url_len;
+    private int field_7_label_len;
+    private String field_8_label;
+    private byte[] field_9_unknown;
+    private String field_10_url;
+
+    /** Blank Constructor */
+    public HyperlinkRecord()
+    {
+    }
+
+    /** Real Constructor */
+    public HyperlinkRecord(RecordInputStream in)
+    {
+        super(in);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#getColumn()
+     */
+    public short getColumn()
+    {
+        return field_2_column;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#getRow()
+     */
+    public int getRow()
+    {
+        return field_1_row;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#getXFIndex()
+     */
+    public short getXFIndex()
+    {
+        return field_3_xf_index;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#isAfter(org.apache.poi.hssf.record.CellValueRecordInterface)
+     */
+    public boolean isAfter(CellValueRecordInterface i)
+    {
+        if (this.getRow() < i.getRow())
+        {
+            return false;
+        }
+        if ((this.getRow() == i.getRow()) && (this.getColumn() < i.getColumn()))
+        {
+            return false;
+        }
+        if ((this.getRow() == i.getRow()) && (this.getColumn() == i.getColumn()))
+        {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#isBefore(org.apache.poi.hssf.record.CellValueRecordInterface)
+     */
+    public boolean isBefore(CellValueRecordInterface i)
+    {
+        if (this.getRow() > i.getRow())
+        {
+            return false;
+        }
+        if ((this.getRow() == i.getRow()) && (this.getColumn() > i.getColumn()))
+        {
+            return false;
+        }
+        if ((this.getRow() == i.getRow()) && (this.getColumn() == i.getColumn()))
+        {
+            return false;
+        }
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#isEqual(org.apache.poi.hssf.record.CellValueRecordInterface)
+     */
+    public boolean isEqual(CellValueRecordInterface i)
+    {
+        return ((this.getRow() == i.getRow()) && (this.getColumn() == i.getColumn()));
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#setColumn(short)
+     */
+    public void setColumn(short col)
+    {
+        this.field_2_column = col;
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#setRow(int)
+     */
+    public void setRow(int row)
+    {
+        this.field_1_row = row;
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.CellValueRecordInterface#setXFIndex(short)
+     */
+    public void setXFIndex(short xf)
+    {
+        this.field_3_xf_index = xf;
+
+    }
+
+    /**
+     * @param in the RecordInputstream to read the record from
+     */
+    protected void fillFields(RecordInputStream in)
+    {
+        field_1_row = in.readUShort(); 
+        field_2_column = in.readShort();
+        field_3_xf_index = in.readShort();
+        field_4_unknown = in.readShort();
+        
+        // Next up is 20 bytes we don't get
+        field_5_unknown = new byte[20];
+        try {
+        in.read(field_5_unknown);
+        } catch(IOException e) { throw new IllegalStateException(e); }
+        
+        // Now for lengths, in characters
+        field_6_url_len = in.readInt();
+        field_7_label_len = in.readInt();
+        
+        // Now we have the label, as little endian unicode,
+        //  with a trailing \0
+        field_8_label = in.readUnicodeLEString(field_7_label_len);
+        
+        // Next up is some more data we can't make sense of
+        field_9_unknown = new byte[20];
+        try {
+        in.read(field_9_unknown);
+        } catch(IOException e) { throw new IllegalStateException(e); }
+        
+        // Finally it's the URL
+        field_10_url = in.readUnicodeLEString(field_6_url_len);
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.poi.hssf.record.Record#getSid()
+     */
+    public short getSid()
+    {
+        return HyperlinkRecord.sid;
+    }
+
+    protected void validateSid(short id)
+    {
+        if (id != sid)
+        {
+            throw new RecordFormatException("NOT A HYPERLINKRECORD!");
+        }
+    }
+
+    public int serialize(int offset, byte[] data)
+    {
+        LittleEndian.putShort(data, 0 + offset, sid);
+        LittleEndian.putShort(data, 2 + offset,
+                              ( short )(getRecordSize()-4));
+        LittleEndian.putUShort(data, 4 + offset, field_1_row);
+        LittleEndian.putShort(data, 6 + offset, field_2_column);
+        LittleEndian.putShort(data, 8 + offset, field_3_xf_index);
+        LittleEndian.putShort(data, 10 + offset, field_4_unknown);
+        
+        offset += 12;
+        for(int i=0; i<field_5_unknown.length; i++) {
+               data[offset] = field_5_unknown[i];
+               offset++;
+        }
+        
+        LittleEndian.putInt(data, offset, field_6_url_len);
+        offset += 4;
+        LittleEndian.putInt(data, offset, field_7_label_len);
+        offset += 4;
+        StringUtil.putUnicodeLE(field_8_label, data, offset);
+        offset += field_8_label.length()*2;
+
+        for(int i=0; i<field_9_unknown.length; i++) {
+               data[offset] = field_9_unknown[i];
+               offset++;
+        }
+       
+        StringUtil.putUnicodeLE(field_10_url, data, offset);
+        
+       return getRecordSize();
+    }
+
+    public int getRecordSize()
+    {
+       // We have:
+       // 4 shorts
+       // junk
+       // 2 ints
+       // label
+       // junk
+       // url
+       return 4 + 4*2 + field_5_unknown.length +
+               2*4 + field_8_label.length()*2 +
+               field_9_unknown.length +
+               field_10_url.length()*2;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer();
+
+        buffer.append("[HYPERLINK RECORD]\n");
+        buffer.append("    .row            = ").append(Integer.toHexString(getRow())).append("\n");
+        buffer.append("    .column         = ").append(Integer.toHexString(getColumn())).append("\n");
+        buffer.append("    .xfindex        = ").append(Integer.toHexString(getXFIndex())).append("\n");
+        buffer.append("    .label          = ").append(field_8_label).append("\n");
+        buffer.append("    .url            = ").append(field_10_url).append("\n");
+        buffer.append("[/HYPERLINK RECORD]\n");
+        return buffer.toString();
+    }
+
+    /**
+     * @return Returns the label.
+     */
+    public String getLabel()
+    {
+       if(field_8_label.length() == 0) {
+               return "";
+       } else {
+               // Trim off \0
+            return field_8_label.substring(0, field_8_label.length() - 1);
+       }
+    }
+
+    /**
+     * @param label The label to set.
+     */
+    public void setLabel(String label)
+    {
+        this.field_8_label = label + '\u0000';
+        this.field_7_label_len = field_8_label.length();
+    }
+
+    /**
+     * @return Returns the Url.
+     */
+    public URL getUrl() throws MalformedURLException
+    {
+        return new URL(getUrlString());
+    }
+    public String getUrlString()
+    {
+       if(field_10_url.length() == 0) {
+               return "";
+       } else {
+               // Trim off \0
+            return field_10_url.substring(0, field_10_url.length() - 1);
+       }
+    }
+
+    /**
+     * @param url The url to set.
+     */
+    public void setUrl(URL url)
+    {
+       setUrl(url.toString());
+    }
+    /**
+     * @param url The url to set.
+     */
+    public void setUrl(String url)
+    {
+        this.field_10_url = url + '\u0000';
+        this.field_6_url_len = field_10_url.length();
+    }
+}
diff --git a/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java b/src/testcases/org/apache/poi/hssf/record/TestHyperlinkRecord.java
new file mode 100644 (file)
index 0000000..587548b
--- /dev/null
@@ -0,0 +1,84 @@
+/* ====================================================================
+   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.hssf.record;
+
+import java.io.ByteArrayInputStream;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+public class TestHyperlinkRecord extends TestCase {
+       protected void setUp() throws Exception {
+               super.setUp();
+       }
+
+       private byte[] data = new byte[] { 
+               -72, 1, 110, 0,
+               // Row, col, xf, ??
+               6, 0, 3, 0,     2, 0, 2, 0, 
+               
+               // ??
+               -48, -55, -22, 121, -7, -70, -50, 17, 
+               -116, -126, 0, -86, 0, 75, -87, 11, 
+               2, 0, 0, 0, 
+               
+               // URL length
+               23, 0, 0, 0, 
+               
+               // Label length
+               4, 0, 0, 0,
+               
+               // Label
+               76, 0, 44, 0, 65, 0, 0, 0, 
+               
+               // ??
+               -32, -55, -22, 121, -7, -70, -50, 17,
+               -116, -126, 0, -86, 0, 75, -87, 11, 
+               46, 0, 0, 0,
+               
+               // URL
+               104, 0, 116, 0, 116, 0, 112, 0, 58, 0, 47, 0, 47, 0, 119,
+               0, 119, 0, 119, 0, 46, 0, 108, 0, 97, 0, 107, 0, 105,
+               0, 110, 0, 103, 0, 115, 0, 46, 0, 99, 0, 111, 0,
+               109, 0, 
+               0, 0 };
+
+       public void testRecordParsing() throws Exception {
+        RecordInputStream inp = new RecordInputStream(
+                new ByteArrayInputStream(data)
+        );
+        inp.nextRecord();
+
+        HyperlinkRecord r = new HyperlinkRecord(inp);
+        
+        assertEquals(6, r.getRow());
+        assertEquals(3, r.getColumn());
+        assertEquals(2, r.getXFIndex());
+        
+        assertEquals("L,A", r.getLabel());
+        assertEquals("http://www.lakings.com", r.getUrlString());
+        assertEquals(new URL("http://www.lakings.com"), r.getUrl());
+        
+        // Check it serialises as expected
+        assertEquals(data.length, r.getRecordSize());
+        byte[] d = r.serialize();
+        assertEquals(data.length, d.length);
+        for(int i=0; i<data.length; i++) {
+               assertEquals(data[i], d[i]);
+        }
+       }
+}