Make a start on the hyperlink record support - not finished yet though, so not enabled

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@617516 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2008-02-01 15:20:55 +00:00
parent 2f93d9dbe4
commit dafc074271
2 changed files with 434 additions and 0 deletions

View File

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

View File

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