mirror of https://github.com/apache/poi.git
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:
parent
2f93d9dbe4
commit
dafc074271
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue