From 4a727300a7a32ea70f570bc5d9fe6dcfe6aa4fae Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Mon, 2 Nov 2015 09:40:49 +0000 Subject: [PATCH] bug 58572: move getHyperlinkList() and getHyperlink(row, col) from XSSFSheet to Sheet git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1711923 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/usermodel/HSSFCell.java | 13 ++---- .../poi/hssf/usermodel/HSSFHyperlink.java | 33 ++++++++++++- .../apache/poi/hssf/usermodel/HSSFSheet.java | 41 +++++++++++++++++ .../apache/poi/ss/usermodel/Hyperlink.java | 9 +++- .../org/apache/poi/ss/usermodel/Sheet.java | 16 +++++++ .../apache/poi/xssf/streaming/SXSSFCell.java | 2 + .../apache/poi/xssf/streaming/SXSSFSheet.java | 23 ++++++++++ .../poi/xssf/usermodel/XSSFHyperlink.java | 16 +++++-- .../apache/poi/xssf/usermodel/XSSFSheet.java | 2 + .../poi/ss/usermodel/BaseTestHyperlink.java | 46 +++++++++++++++++++ 10 files changed, 184 insertions(+), 17 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index d36347549b..ad3635de6c 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -1045,17 +1045,9 @@ public class HSSFCell implements Cell { /** * @return hyperlink associated with this cell or null if not found */ + @Override public HSSFHyperlink getHyperlink(){ - for (Iterator it = _sheet.getSheet().getRecords().iterator(); it.hasNext(); ) { - RecordBase rec = it.next(); - if (rec instanceof HyperlinkRecord){ - HyperlinkRecord link = (HyperlinkRecord)rec; - if(link.getFirstColumn() == _record.getColumn() && link.getFirstRow() == _record.getRow()){ - return new HSSFHyperlink(link); - } - } - } - return null; + return _sheet.getHyperlink(_record.getRow(), _record.getColumn()); } /** @@ -1064,6 +1056,7 @@ public class HSSFCell implements Cell { * * @param hyperlink hyperlink associated with this cell */ + @Override public void setHyperlink(Hyperlink hyperlink){ if (hyperlink == null) { removeHyperlink(); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java index 5cb8e77163..f7010b5f18 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFHyperlink.java @@ -47,12 +47,12 @@ public class HSSFHyperlink implements Hyperlink { /** * Low-level record object that stores the actual hyperlink data */ - protected HyperlinkRecord record = null; + final protected HyperlinkRecord record; /** * If we create a new hyperlink remember its type */ - protected int link_type; + final protected int link_type; /** * Construct a new hyperlink @@ -100,6 +100,19 @@ public class HSSFHyperlink implements Hyperlink { } } } + + @Override + public HSSFHyperlink clone() { + return new HSSFHyperlink(record.clone()); + /*final HSSFHyperlink link = new HSSFHyperlink(link_type); + link.setLabel(getLabel()); + link.setAddress(getAddress()); + link.setFirstColumn(getFirstColumn()); + link.setFirstRow(getFirstRow()); + link.setLastColumn(getLastColumn()); + link.setLastRow(getLastRow()); + return link;*/ + } /** * Return the row of the first cell that contains the hyperlink @@ -240,4 +253,20 @@ public class HSSFHyperlink implements Hyperlink { public int getType(){ return link_type; } + + /** + * @return whether the objects have the same HyperlinkRecord + */ + @Override + public boolean equals(Object other) { + if (this == other) return true; + if (!(other instanceof HSSFHyperlink)) return false; + HSSFHyperlink otherLink = (HSSFHyperlink) other; + return record == otherLink.record; + } + + @Override + public int hashCode() { + return record.hashCode(); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java index 4d28ef62fc..8f8756ed96 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java @@ -35,8 +35,10 @@ import org.apache.poi.hssf.record.DimensionsRecord; import org.apache.poi.hssf.record.DrawingRecord; import org.apache.poi.hssf.record.EscherAggregate; import org.apache.poi.hssf.record.ExtendedFormatRecord; +import org.apache.poi.hssf.record.HyperlinkRecord; import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RecordBase; import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.hssf.record.SCLRecord; import org.apache.poi.hssf.record.WSBoolRecord; @@ -2046,6 +2048,45 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { public HSSFComment getCellComment(int row, int column) { return findCellComment(row, column); } + + /** + * Get a Hyperlink in this sheet anchored at row, column + * + * @param row + * @param column + * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null + */ + @Override + public HSSFHyperlink getHyperlink(int row, int column) { + for (Iterator it = _sheet.getRecords().iterator(); it.hasNext(); ) { + RecordBase rec = it.next(); + if (rec instanceof HyperlinkRecord){ + HyperlinkRecord link = (HyperlinkRecord)rec; + if (link.getFirstColumn() == column && link.getFirstRow() == row) { + return new HSSFHyperlink(link); + } + } + } + return null; + } + + /** + * Get a list of Hyperlinks in this sheet + * + * @return Hyperlinks for the sheet + */ + @Override + public List getHyperlinkList() { + final List hyperlinkList = new ArrayList(); + for (Iterator it = _sheet.getRecords().iterator(); it.hasNext(); ) { + RecordBase rec = it.next(); + if (rec instanceof HyperlinkRecord){ + HyperlinkRecord link = (HyperlinkRecord)rec; + hyperlinkList.add(new HSSFHyperlink(link)); + } + } + return hyperlinkList; + } public HSSFSheetConditionalFormatting getSheetConditionalFormatting() { return new HSSFSheetConditionalFormatting(this); diff --git a/src/java/org/apache/poi/ss/usermodel/Hyperlink.java b/src/java/org/apache/poi/ss/usermodel/Hyperlink.java index c067cc002c..35ceb7863e 100644 --- a/src/java/org/apache/poi/ss/usermodel/Hyperlink.java +++ b/src/java/org/apache/poi/ss/usermodel/Hyperlink.java @@ -19,7 +19,7 @@ package org.apache.poi.ss.usermodel; /** * Represents an Excel hyperlink. */ -public interface Hyperlink extends org.apache.poi.common.usermodel.Hyperlink { +public interface Hyperlink extends org.apache.poi.common.usermodel.Hyperlink, Cloneable { /** * Return the row of the first cell that contains the hyperlink * @@ -75,4 +75,11 @@ public interface Hyperlink extends org.apache.poi.common.usermodel.Hyperlink { * @param col the 0-based column of the last cell that contains the hyperlink */ public void setLastColumn(int col); + + /** + * Create a clone of this hyperlink + * + * @return clone of this Hyperlink + */ + public Hyperlink clone(); } diff --git a/src/java/org/apache/poi/ss/usermodel/Sheet.java b/src/java/org/apache/poi/ss/usermodel/Sheet.java index f0990511ff..034b94de4a 100644 --- a/src/java/org/apache/poi/ss/usermodel/Sheet.java +++ b/src/java/org/apache/poi/ss/usermodel/Sheet.java @@ -1067,4 +1067,20 @@ public interface Sheet extends Iterable { * you take it out of them. */ int getColumnOutlineLevel(int columnIndex); + + /** + * Get a Hyperlink in this sheet anchored at row, column + * + * @param row + * @param column + * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null + */ + public Hyperlink getHyperlink(int row, int column); + + /** + * Get a list of Hyperlinks in this sheet + * + * @return Hyperlinks for the sheet + */ + public List getHyperlinkList(); } diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java index 126d90c335..e4dd721dab 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -579,6 +579,7 @@ public class SXSSFCell implements Cell { /** * @return hyperlink associated with this cell or null if not found */ + @Override public Hyperlink getHyperlink() { return (Hyperlink)getPropertyValue(Property.HYPERLINK); @@ -590,6 +591,7 @@ public class SXSSFCell implements Cell { * * @param link hyperlink associated with this cell */ + @Override public void setHyperlink(Hyperlink link) { if (link == null) { diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index 0094976530..72e782adb6 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -44,6 +44,7 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.SheetUtil; import org.apache.poi.xssf.usermodel.XSSFDataValidation; +import org.apache.poi.xssf.usermodel.XSSFHyperlink; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; @@ -1326,6 +1327,28 @@ public class SXSSFSheet implements Sheet, Cloneable { return _sh.getCellComment(row, column); } + + /** + * Get a Hyperlink in this sheet anchored at row, column + * + * @param row + * @param column + * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null + */ + @Override + public XSSFHyperlink getHyperlink(int row, int column) { + return _sh.getHyperlink(row, column); + } + + /** + * Get a list of Hyperlinks in this sheet + * + * @return Hyperlinks for the sheet + */ + @Override + public List getHyperlinkList() { + return _sh.getHyperlinkList(); + } /** * Creates the top-level drawing patriarch. diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java index b338e3eed7..fdf7759ec6 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFHyperlink.java @@ -32,9 +32,9 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink; * are largely stored as relations of the sheet */ public class XSSFHyperlink implements Hyperlink { - private int _type; - private PackageRelationship _externalRel; - private CTHyperlink _ctHyperlink; //contains a reference to the cell where the hyperlink is anchored, getRef() + final private int _type; + final private PackageRelationship _externalRel; + final private CTHyperlink _ctHyperlink; //contains a reference to the cell where the hyperlink is anchored, getRef() private String _location; //what the hyperlink refers to /** @@ -45,10 +45,11 @@ public class XSSFHyperlink implements Hyperlink { protected XSSFHyperlink(int type) { _type = type; _ctHyperlink = CTHyperlink.Factory.newInstance(); + _externalRel = null; } /** - * Create a XSSFHyperlink amd initialize it from the supplied CTHyperlink bean and package relationship + * Create a XSSFHyperlink and initialize it from the supplied CTHyperlink bean and package relationship * * @param ctHyperlink the xml bean containing xml properties * @param hyperlinkRel the relationship in the underlying OPC package which stores the actual link's address @@ -91,6 +92,13 @@ public class XSSFHyperlink implements Hyperlink { } } + + @Override + public Hyperlink clone() { + final XSSFHyperlink clone = new XSSFHyperlink((CTHyperlink) _ctHyperlink.copy(), _externalRel); + clone.setLocation(_location); + return clone; + } /** * @return the underlying CTHyperlink object diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index e9ef3a2ffd..56cd1e7499 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -703,6 +703,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { * @param column * @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null */ + @Override public XSSFHyperlink getHyperlink(int row, int column) { String ref = new CellReference(row, column).formatAsString(); for(XSSFHyperlink hyperlink : hyperlinks) { @@ -718,6 +719,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { * * @return Hyperlinks for the sheet */ + @Override public List getHyperlinkList() { return Collections.unmodifiableList(hyperlinks); } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestHyperlink.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestHyperlink.java index 51148f8041..4be6de3a71 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestHyperlink.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestHyperlink.java @@ -18,6 +18,11 @@ package org.apache.poi.ss.usermodel; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotSame; + +import java.util.List; + import org.junit.Test; import org.apache.poi.ss.ITestDataProvider; @@ -91,4 +96,45 @@ public abstract class BaseTestHyperlink { link = sheet.getRow(3).getCell(0).getHyperlink(); assertEquals("'Target Sheet'!A1", link.getAddress()); } + + @Test + public void testClone() { + System.out.println("testClone"); + final Workbook wb = _testDataProvider.createWorkbook(); + final CreationHelper createHelper = wb.getCreationHelper(); + + final Sheet sheet = wb.createSheet("Hyperlinks"); + final Row row = sheet.createRow(0); + final Cell cell1, cell2; + final Hyperlink link1, link2; + + //URL + cell1 = row.createCell(0); + cell2 = row.createCell(1); + cell1.setCellValue("URL Link"); + link1 = createHelper.createHyperlink(Hyperlink.LINK_URL); + link1.setAddress("http://poi.apache.org/"); + cell1.setHyperlink(link1); + + link2 = link1.clone(); + + // Change address (type is not changeable) + link2.setAddress("http://apache.org/"); + cell2.setHyperlink(link2); + + // Make sure hyperlinks were deep-copied, and modifying one does not modify the other. + assertNotSame(link1, link2); + assertNotEquals(link1, link2); + assertEquals("http://poi.apache.org/", link1.getAddress()); + assertEquals("http://apache.org/", link2.getAddress()); + assertEquals(link1, cell1.getHyperlink()); + assertEquals(link2, cell2.getHyperlink()); + + // Make sure both hyperlinks were added to the sheet + @SuppressWarnings("unchecked") + final List actualHyperlinks = (List) sheet.getHyperlinkList(); + assertEquals(2, actualHyperlinks.size()); + assertEquals(link1, actualHyperlinks.get(0)); + assertEquals(link2, actualHyperlinks.get(1)); + } } -- 2.39.5