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
219b26ac3e
commit
dc92ea3725
350
src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
Normal file
350
src/java/org/apache/poi/hssf/record/HyperlinkRecord.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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
Block a user