first commit
This commit is contained in:
558
hrmsEjb/jxl/write/biff/HyperlinkRecord.java
Normal file
558
hrmsEjb/jxl/write/biff/HyperlinkRecord.java
Normal file
@@ -0,0 +1,558 @@
|
||||
package jxl.write.biff;
|
||||
|
||||
import common.Assert;
|
||||
import common.Logger;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import jxl.CellType;
|
||||
import jxl.Hyperlink;
|
||||
import jxl.Range;
|
||||
import jxl.Sheet;
|
||||
import jxl.biff.CellReferenceHelper;
|
||||
import jxl.biff.IntegerHelper;
|
||||
import jxl.biff.SheetRangeImpl;
|
||||
import jxl.biff.StringHelper;
|
||||
import jxl.biff.Type;
|
||||
import jxl.biff.WritableRecordData;
|
||||
import jxl.write.Label;
|
||||
import jxl.write.WritableCell;
|
||||
import jxl.write.WritableSheet;
|
||||
|
||||
public class HyperlinkRecord extends WritableRecordData {
|
||||
private static Logger logger = Logger.getLogger(HyperlinkRecord.class);
|
||||
|
||||
private int firstRow;
|
||||
|
||||
private int lastRow;
|
||||
|
||||
private int firstColumn;
|
||||
|
||||
private int lastColumn;
|
||||
|
||||
private URL url;
|
||||
|
||||
private File file;
|
||||
|
||||
private String location;
|
||||
|
||||
private String contents;
|
||||
|
||||
private LinkType linkType;
|
||||
|
||||
private byte[] data;
|
||||
|
||||
private Range range;
|
||||
|
||||
private WritableSheet sheet;
|
||||
|
||||
private boolean modified;
|
||||
|
||||
private static class LinkType {
|
||||
private LinkType() {}
|
||||
}
|
||||
|
||||
private static final LinkType urlLink = new LinkType();
|
||||
|
||||
private static final LinkType fileLink = new LinkType();
|
||||
|
||||
private static final LinkType uncLink = new LinkType();
|
||||
|
||||
private static final LinkType workbookLink = new LinkType();
|
||||
|
||||
private static final LinkType unknown = new LinkType();
|
||||
|
||||
protected HyperlinkRecord(Hyperlink h, WritableSheet s) {
|
||||
super(Type.HLINK);
|
||||
Assert.verify(h instanceof jxl.read.biff.HyperlinkRecord);
|
||||
jxl.read.biff.HyperlinkRecord hl = (jxl.read.biff.HyperlinkRecord)h;
|
||||
this.data = hl.getRecord().getData();
|
||||
this.sheet = s;
|
||||
this.firstRow = hl.getRow();
|
||||
this.firstColumn = hl.getColumn();
|
||||
this.lastRow = hl.getLastRow();
|
||||
this.lastColumn = hl.getLastColumn();
|
||||
this.range = (Range)new SheetRangeImpl((Sheet)s, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
|
||||
this.linkType = unknown;
|
||||
if (hl.isFile()) {
|
||||
this.linkType = fileLink;
|
||||
this.file = hl.getFile();
|
||||
} else if (hl.isURL()) {
|
||||
this.linkType = urlLink;
|
||||
this.url = hl.getURL();
|
||||
} else if (hl.isLocation()) {
|
||||
this.linkType = workbookLink;
|
||||
this.location = hl.getLocation();
|
||||
}
|
||||
this.modified = false;
|
||||
}
|
||||
|
||||
protected HyperlinkRecord(int col, int row, int lastcol, int lastrow, URL url, String desc) {
|
||||
super(Type.HLINK);
|
||||
this.firstColumn = col;
|
||||
this.firstRow = row;
|
||||
this.lastColumn = Math.max(this.firstColumn, lastcol);
|
||||
this.lastRow = Math.max(this.firstRow, lastrow);
|
||||
this.url = url;
|
||||
this.contents = desc;
|
||||
this.linkType = urlLink;
|
||||
this.modified = true;
|
||||
}
|
||||
|
||||
protected HyperlinkRecord(int col, int row, int lastcol, int lastrow, File file, String desc) {
|
||||
super(Type.HLINK);
|
||||
this.firstColumn = col;
|
||||
this.firstRow = row;
|
||||
this.lastColumn = Math.max(this.firstColumn, lastcol);
|
||||
this.lastRow = Math.max(this.firstRow, lastrow);
|
||||
this.contents = desc;
|
||||
this.file = file;
|
||||
if (file.getPath().startsWith("\\\\")) {
|
||||
this.linkType = uncLink;
|
||||
} else {
|
||||
this.linkType = fileLink;
|
||||
}
|
||||
this.modified = true;
|
||||
}
|
||||
|
||||
protected HyperlinkRecord(int col, int row, int lastcol, int lastrow, String desc, WritableSheet s, int destcol, int destrow, int lastdestcol, int lastdestrow) {
|
||||
super(Type.HLINK);
|
||||
this.firstColumn = col;
|
||||
this.firstRow = row;
|
||||
this.lastColumn = Math.max(this.firstColumn, lastcol);
|
||||
this.lastRow = Math.max(this.firstRow, lastrow);
|
||||
setLocation(s, destcol, destrow, lastdestcol, lastdestrow);
|
||||
this.contents = desc;
|
||||
this.linkType = workbookLink;
|
||||
this.modified = true;
|
||||
}
|
||||
|
||||
public boolean isFile() {
|
||||
return (this.linkType == fileLink);
|
||||
}
|
||||
|
||||
public boolean isUNC() {
|
||||
return (this.linkType == uncLink);
|
||||
}
|
||||
|
||||
public boolean isURL() {
|
||||
return (this.linkType == urlLink);
|
||||
}
|
||||
|
||||
public boolean isLocation() {
|
||||
return (this.linkType == workbookLink);
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return this.firstRow;
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return this.firstColumn;
|
||||
}
|
||||
|
||||
public int getLastRow() {
|
||||
return this.lastRow;
|
||||
}
|
||||
|
||||
public int getLastColumn() {
|
||||
return this.lastColumn;
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return this.file;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
if (!this.modified)
|
||||
return this.data;
|
||||
byte[] commonData = new byte[32];
|
||||
IntegerHelper.getTwoBytes(this.firstRow, commonData, 0);
|
||||
IntegerHelper.getTwoBytes(this.lastRow, commonData, 2);
|
||||
IntegerHelper.getTwoBytes(this.firstColumn, commonData, 4);
|
||||
IntegerHelper.getTwoBytes(this.lastColumn, commonData, 6);
|
||||
commonData[8] = -48;
|
||||
commonData[9] = -55;
|
||||
commonData[10] = -22;
|
||||
commonData[11] = 121;
|
||||
commonData[12] = -7;
|
||||
commonData[13] = -70;
|
||||
commonData[14] = -50;
|
||||
commonData[15] = 17;
|
||||
commonData[16] = -116;
|
||||
commonData[17] = -126;
|
||||
commonData[18] = 0;
|
||||
commonData[19] = -86;
|
||||
commonData[20] = 0;
|
||||
commonData[21] = 75;
|
||||
commonData[22] = -87;
|
||||
commonData[23] = 11;
|
||||
commonData[24] = 2;
|
||||
commonData[25] = 0;
|
||||
commonData[26] = 0;
|
||||
commonData[27] = 0;
|
||||
int optionFlags = 0;
|
||||
if (isURL()) {
|
||||
optionFlags = 3;
|
||||
if (this.contents != null)
|
||||
optionFlags |= 0x14;
|
||||
} else if (isFile()) {
|
||||
optionFlags = 3;
|
||||
if (this.contents == null)
|
||||
optionFlags |= 0x14;
|
||||
} else if (isLocation()) {
|
||||
optionFlags = 8;
|
||||
} else if (isUNC()) {
|
||||
optionFlags = 259;
|
||||
}
|
||||
IntegerHelper.getFourBytes(optionFlags, commonData, 28);
|
||||
if (isURL()) {
|
||||
this.data = getURLData(commonData);
|
||||
} else if (isFile()) {
|
||||
this.data = getFileData(commonData);
|
||||
} else if (isLocation()) {
|
||||
this.data = getLocationData(commonData);
|
||||
} else if (isUNC()) {
|
||||
this.data = getUNCData(commonData);
|
||||
}
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (isFile())
|
||||
return this.file.toString();
|
||||
if (isURL())
|
||||
return this.url.toString();
|
||||
if (isUNC())
|
||||
return this.file.toString();
|
||||
return "";
|
||||
}
|
||||
|
||||
public Range getRange() {
|
||||
return this.range;
|
||||
}
|
||||
|
||||
public void setURL(URL url) {
|
||||
this.linkType = urlLink;
|
||||
this.file = null;
|
||||
this.location = null;
|
||||
this.contents = null;
|
||||
this.url = url;
|
||||
this.modified = true;
|
||||
if (this.sheet == null)
|
||||
return;
|
||||
WritableCell wc = this.sheet.getWritableCell(this.firstColumn, this.firstRow);
|
||||
Assert.verify((wc.getType() == CellType.LABEL));
|
||||
Label l = (Label)wc;
|
||||
l.setString(url.toString());
|
||||
}
|
||||
|
||||
public void setFile(File file) {
|
||||
this.linkType = fileLink;
|
||||
this.url = null;
|
||||
this.location = null;
|
||||
this.contents = null;
|
||||
this.file = file;
|
||||
this.modified = true;
|
||||
if (this.sheet == null)
|
||||
return;
|
||||
WritableCell wc = this.sheet.getWritableCell(this.firstColumn, this.firstRow);
|
||||
Assert.verify((wc.getType() == CellType.LABEL));
|
||||
Label l = (Label)wc;
|
||||
l.setString(file.toString());
|
||||
}
|
||||
|
||||
protected void setLocation(String desc, WritableSheet sheet, int destcol, int destrow, int lastdestcol, int lastdestrow) {
|
||||
this.linkType = workbookLink;
|
||||
this.url = null;
|
||||
this.file = null;
|
||||
this.modified = true;
|
||||
this.contents = desc;
|
||||
setLocation(sheet, destcol, destrow, lastdestcol, lastdestrow);
|
||||
if (sheet == null)
|
||||
return;
|
||||
WritableCell wc = sheet.getWritableCell(this.firstColumn, this.firstRow);
|
||||
Assert.verify((wc.getType() == CellType.LABEL));
|
||||
Label l = (Label)wc;
|
||||
l.setString(desc);
|
||||
}
|
||||
|
||||
private void setLocation(WritableSheet sheet, int destcol, int destrow, int lastdestcol, int lastdestrow) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append('\'');
|
||||
if (sheet.getName().indexOf('\'') == -1) {
|
||||
sb.append(sheet.getName());
|
||||
} else {
|
||||
String sheetName = sheet.getName();
|
||||
int pos = 0;
|
||||
int nextPos = sheetName.indexOf('\'', pos);
|
||||
while (nextPos != -1 && pos < sheetName.length()) {
|
||||
sb.append(sheetName.substring(pos, nextPos));
|
||||
sb.append("''");
|
||||
pos = nextPos + 1;
|
||||
nextPos = sheetName.indexOf('\'', pos);
|
||||
}
|
||||
sb.append(sheetName.substring(pos));
|
||||
}
|
||||
sb.append('\'');
|
||||
sb.append('!');
|
||||
lastdestcol = Math.max(destcol, lastdestcol);
|
||||
lastdestrow = Math.max(destrow, lastdestrow);
|
||||
CellReferenceHelper.getCellReference(destcol, destrow, sb);
|
||||
sb.append(':');
|
||||
CellReferenceHelper.getCellReference(lastdestcol, lastdestrow, sb);
|
||||
this.location = sb.toString();
|
||||
}
|
||||
|
||||
void insertRow(int r) {
|
||||
Assert.verify((this.sheet != null && this.range != null));
|
||||
if (r > this.lastRow)
|
||||
return;
|
||||
if (r <= this.firstRow) {
|
||||
this.firstRow++;
|
||||
this.modified = true;
|
||||
}
|
||||
if (r <= this.lastRow) {
|
||||
this.lastRow++;
|
||||
this.modified = true;
|
||||
}
|
||||
if (this.modified)
|
||||
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
|
||||
}
|
||||
|
||||
void insertColumn(int c) {
|
||||
Assert.verify((this.sheet != null && this.range != null));
|
||||
if (c > this.lastColumn)
|
||||
return;
|
||||
if (c <= this.firstColumn) {
|
||||
this.firstColumn++;
|
||||
this.modified = true;
|
||||
}
|
||||
if (c <= this.lastColumn) {
|
||||
this.lastColumn++;
|
||||
this.modified = true;
|
||||
}
|
||||
if (this.modified)
|
||||
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
|
||||
}
|
||||
|
||||
void removeRow(int r) {
|
||||
Assert.verify((this.sheet != null && this.range != null));
|
||||
if (r > this.lastRow)
|
||||
return;
|
||||
if (r < this.firstRow) {
|
||||
this.firstRow--;
|
||||
this.modified = true;
|
||||
}
|
||||
if (r < this.lastRow) {
|
||||
this.lastRow--;
|
||||
this.modified = true;
|
||||
}
|
||||
if (this.modified) {
|
||||
Assert.verify((this.range != null));
|
||||
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
|
||||
}
|
||||
}
|
||||
|
||||
void removeColumn(int c) {
|
||||
Assert.verify((this.sheet != null && this.range != null));
|
||||
if (c > this.lastColumn)
|
||||
return;
|
||||
if (c < this.firstColumn) {
|
||||
this.firstColumn--;
|
||||
this.modified = true;
|
||||
}
|
||||
if (c < this.lastColumn) {
|
||||
this.lastColumn--;
|
||||
this.modified = true;
|
||||
}
|
||||
if (this.modified) {
|
||||
Assert.verify((this.range != null));
|
||||
this.range = (Range)new SheetRangeImpl((Sheet)this.sheet, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getURLData(byte[] cd) {
|
||||
String urlString = this.url.toString();
|
||||
int dataLength = cd.length + 20 + (urlString.length() + 1) * 2;
|
||||
if (this.contents != null)
|
||||
dataLength += 4 + (this.contents.length() + 1) * 2;
|
||||
byte[] d = new byte[dataLength];
|
||||
System.arraycopy(cd, 0, d, 0, cd.length);
|
||||
int urlPos = cd.length;
|
||||
if (this.contents != null) {
|
||||
IntegerHelper.getFourBytes(this.contents.length() + 1, d, urlPos);
|
||||
StringHelper.getUnicodeBytes(this.contents, d, urlPos + 4);
|
||||
urlPos += (this.contents.length() + 1) * 2 + 4;
|
||||
}
|
||||
d[urlPos] = -32;
|
||||
d[urlPos + 1] = -55;
|
||||
d[urlPos + 2] = -22;
|
||||
d[urlPos + 3] = 121;
|
||||
d[urlPos + 4] = -7;
|
||||
d[urlPos + 5] = -70;
|
||||
d[urlPos + 6] = -50;
|
||||
d[urlPos + 7] = 17;
|
||||
d[urlPos + 8] = -116;
|
||||
d[urlPos + 9] = -126;
|
||||
d[urlPos + 10] = 0;
|
||||
d[urlPos + 11] = -86;
|
||||
d[urlPos + 12] = 0;
|
||||
d[urlPos + 13] = 75;
|
||||
d[urlPos + 14] = -87;
|
||||
d[urlPos + 15] = 11;
|
||||
IntegerHelper.getFourBytes((urlString.length() + 1) * 2, d, urlPos + 16);
|
||||
StringHelper.getUnicodeBytes(urlString, d, urlPos + 20);
|
||||
return d;
|
||||
}
|
||||
|
||||
private byte[] getUNCData(byte[] cd) {
|
||||
String uncString = this.file.getPath();
|
||||
byte[] d = new byte[cd.length + uncString.length() * 2 + 2 + 4];
|
||||
System.arraycopy(cd, 0, d, 0, cd.length);
|
||||
int urlPos = cd.length;
|
||||
int length = uncString.length() + 1;
|
||||
IntegerHelper.getFourBytes(length, d, urlPos);
|
||||
StringHelper.getUnicodeBytes(uncString, d, urlPos + 4);
|
||||
return d;
|
||||
}
|
||||
|
||||
private byte[] getFileData(byte[] cd) {
|
||||
ArrayList path = new ArrayList();
|
||||
ArrayList shortFileName = new ArrayList();
|
||||
path.add(this.file.getName());
|
||||
shortFileName.add(getShortName(this.file.getName()));
|
||||
File parent = this.file.getParentFile();
|
||||
while (parent != null) {
|
||||
path.add(parent.getName());
|
||||
shortFileName.add(getShortName(parent.getName()));
|
||||
parent = parent.getParentFile();
|
||||
}
|
||||
int upLevelCount = 0;
|
||||
int pos = path.size() - 1;
|
||||
boolean upDir = true;
|
||||
while (upDir) {
|
||||
String s = path.get(pos);
|
||||
if (s.equals("..")) {
|
||||
upLevelCount++;
|
||||
path.remove(pos);
|
||||
shortFileName.remove(pos);
|
||||
} else {
|
||||
upDir = false;
|
||||
}
|
||||
pos--;
|
||||
}
|
||||
StringBuffer filePathSB = new StringBuffer();
|
||||
StringBuffer shortFilePathSB = new StringBuffer();
|
||||
if (this.file.getPath().charAt(1) == ':') {
|
||||
char driveLetter = this.file.getPath().charAt(0);
|
||||
if (driveLetter != 'C' && driveLetter != 'c') {
|
||||
filePathSB.append(driveLetter);
|
||||
filePathSB.append(':');
|
||||
shortFilePathSB.append(driveLetter);
|
||||
shortFilePathSB.append(':');
|
||||
}
|
||||
}
|
||||
for (int i = path.size() - 1; i >= 0; i--) {
|
||||
filePathSB.append(path.get(i));
|
||||
shortFilePathSB.append(shortFileName.get(i));
|
||||
if (i != 0) {
|
||||
filePathSB.append("\\");
|
||||
shortFilePathSB.append("\\");
|
||||
}
|
||||
}
|
||||
String filePath = filePathSB.toString();
|
||||
String shortFilePath = shortFilePathSB.toString();
|
||||
int dataLength = cd.length + 4 + (shortFilePath.length() + 1) * 2 + 16 + 2 + 4 + filePath.length() + 1 + 4 + 24;
|
||||
if (this.contents != null)
|
||||
dataLength += 4 + (this.contents.length() + 1) * 2;
|
||||
byte[] d = new byte[dataLength];
|
||||
System.arraycopy(cd, 0, d, 0, cd.length);
|
||||
int filePos = cd.length;
|
||||
if (this.contents != null) {
|
||||
IntegerHelper.getFourBytes(this.contents.length() + 1, d, filePos);
|
||||
StringHelper.getUnicodeBytes(this.contents, d, filePos + 4);
|
||||
filePos += (this.contents.length() + 1) * 2 + 4;
|
||||
}
|
||||
int curPos = filePos;
|
||||
IntegerHelper.getFourBytes(shortFilePath.length() + 1, d, curPos);
|
||||
StringHelper.getUnicodeBytes(shortFilePath, d, curPos + 4);
|
||||
curPos += 4 + (shortFilePath.length() + 1) * 2;
|
||||
d[curPos] = 3;
|
||||
d[curPos + 1] = 3;
|
||||
d[curPos + 2] = 0;
|
||||
d[curPos + 3] = 0;
|
||||
d[curPos + 4] = 0;
|
||||
d[curPos + 5] = 0;
|
||||
d[curPos + 6] = 0;
|
||||
d[curPos + 7] = 0;
|
||||
d[curPos + 8] = -64;
|
||||
d[curPos + 9] = 0;
|
||||
d[curPos + 10] = 0;
|
||||
d[curPos + 11] = 0;
|
||||
d[curPos + 12] = 0;
|
||||
d[curPos + 13] = 0;
|
||||
d[curPos + 14] = 0;
|
||||
d[curPos + 15] = 70;
|
||||
curPos += 16;
|
||||
IntegerHelper.getTwoBytes(upLevelCount, d, curPos);
|
||||
curPos += 2;
|
||||
IntegerHelper.getFourBytes(filePath.length() + 1, d, curPos);
|
||||
curPos += 4;
|
||||
StringHelper.getBytes(filePath, d, curPos);
|
||||
curPos += filePath.length() + 1;
|
||||
d[curPos] = -1;
|
||||
d[curPos + 1] = -1;
|
||||
d[curPos + 2] = -83;
|
||||
d[curPos + 3] = -34;
|
||||
return d;
|
||||
}
|
||||
|
||||
private String getShortName(String s) {
|
||||
int sep = s.indexOf('.');
|
||||
String prefix = null;
|
||||
String suffix = null;
|
||||
if (sep == -1) {
|
||||
prefix = s;
|
||||
suffix = "";
|
||||
} else {
|
||||
prefix = s.substring(0, sep);
|
||||
suffix = s.substring(sep + 1);
|
||||
}
|
||||
if (prefix.length() > 8) {
|
||||
prefix = prefix.substring(0, 6) + "~" + (prefix.length() - 6);
|
||||
prefix = prefix.substring(0, 8);
|
||||
}
|
||||
suffix = suffix.substring(0, Math.min(3, suffix.length()));
|
||||
if (suffix.length() > 0)
|
||||
return prefix + '.' + suffix;
|
||||
return prefix;
|
||||
}
|
||||
|
||||
private byte[] getLocationData(byte[] cd) {
|
||||
byte[] d = new byte[cd.length + 4 + (this.location.length() + 1) * 2];
|
||||
System.arraycopy(cd, 0, d, 0, cd.length);
|
||||
int locPos = cd.length;
|
||||
IntegerHelper.getFourBytes(this.location.length() + 1, d, locPos);
|
||||
StringHelper.getUnicodeBytes(this.location, d, locPos + 4);
|
||||
return d;
|
||||
}
|
||||
|
||||
void initialize(WritableSheet s) {
|
||||
this.sheet = s;
|
||||
this.range = (Range)new SheetRangeImpl((Sheet)s, this.firstColumn, this.firstRow, this.lastColumn, this.lastRow);
|
||||
}
|
||||
|
||||
String getContents() {
|
||||
return this.contents;
|
||||
}
|
||||
|
||||
protected void setContents(String desc) {
|
||||
this.contents = desc;
|
||||
this.modified = true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user