From 60603310811edc4ff6f229b31dca0d8e2baa1229 Mon Sep 17 00:00:00 2001 From: Nick Burch <nick@apache.org> Date: Mon, 14 Jun 2010 15:43:47 +0000 Subject: [PATCH] Fix bug #49432 - Lazy caching of XSSFComment CTComment objects by reference, to make repeated comment searching faster git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@954521 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../apache/poi/xssf/model/CommentsTable.java | 48 +++++++++++++++---- .../poi/xssf/usermodel/XSSFComment.java | 10 +++- .../apache/poi/xssf/usermodel/XSSFSheet.java | 7 ++- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 99c896ee8..4f07ad331 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ <changes> <release version="3.7-beta2" date="2010-??-??"> + <action dev="POI-DEVELOPERS" type="fix">49432 - Lazy caching of XSSFComment CTComment objects by reference, to make repeated comment searching faster</action> <action dev="POI-DEVELOPERS" type="fix">Better handling of Outlook messages in HSMF when there's no recipient email address</action> <action dev="POI-DEVELOPERS" type="fix">When formatting numbers with DataFormatter, handle brackets following colours</action> </release> diff --git a/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java b/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java index da47d90a2..f443be483 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java @@ -19,20 +19,27 @@ package org.apache.poi.xssf.model; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.xssf.usermodel.XSSFComment; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.xssf.usermodel.XSSFComment; import org.apache.xmlbeans.XmlException; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; public class CommentsTable extends POIXMLDocumentPart { private CTComments comments; + /** + * XML Beans uses a list, which is very slow + * to search, so we wrap things with our own + * map for fast lookup. + */ + private Map<String, CTComment> commentRefs; public CommentsTable() { super(); @@ -67,6 +74,17 @@ public class CommentsTable extends POIXMLDocumentPart { writeTo(out); out.close(); } + + /** + * Called after the reference is updated, so that + * we can reflect that in our cache + */ + public void referenceUpdated(String oldReference, CTComment comment) { + if(commentRefs != null) { + commentRefs.remove(oldReference); + commentRefs.put(comment.getRef(), comment); + } + } public int getNumberOfComments() { return comments.getCommentList().sizeOfCommentArray(); @@ -95,18 +113,26 @@ public class CommentsTable extends POIXMLDocumentPart { } public CTComment getCTComment(String cellRef) { - for (CTComment comment : comments.getCommentList().getCommentArray()) { - if (cellRef.equals(comment.getRef())) { - return comment; - } + // Create the cache if needed + if(commentRefs == null) { + commentRefs = new HashMap<String, CTComment>(); + for (CTComment comment : comments.getCommentList().getCommentList()) { + commentRefs.put(comment.getRef(), comment); + } } - return null; + + // Return the comment, or null if not known + return commentRefs.get(cellRef); } public CTComment newComment() { CTComment ct = comments.getCommentList().addNewComment(); ct.setRef("A1"); ct.setAuthorId(0); + + if(commentRefs != null) { + commentRefs.put(ct.getRef(), ct); + } return ct; } @@ -116,6 +142,10 @@ public class CommentsTable extends POIXMLDocumentPart { CTComment comment = lst.getCommentArray(i); if (cellRef.equals(comment.getRef())) { lst.removeComment(i); + + if(commentRefs != null) { + commentRefs.remove(cellRef); + } return true; } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java index a7e577d19..9d6c34cd4 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFComment.java @@ -110,8 +110,12 @@ public class XSSFComment implements Comment { * @param col the 0-based column of the cell that contains the comment */ public void setColumn(int col) { + String oldRef = _comment.getRef(); + CellReference ref = new CellReference(getRow(), col); - _comment.setRef(ref.formatAsString()); + _comment.setRef(ref.formatAsString()); + _comments.referenceUpdated(oldRef, _comment); + if(_vmlShape != null) _vmlShape.getClientDataArray(0).setColumnArray(0, new BigInteger(String.valueOf(col))); } @@ -121,9 +125,13 @@ public class XSSFComment implements Comment { * @param row the 0-based row of the cell that contains the comment */ public void setRow(int row) { + String oldRef = _comment.getRef(); + String newRef = (new CellReference(row, getColumn())).formatAsString(); _comment.setRef(newRef); + _comments.referenceUpdated(oldRef, _comment); + if(_vmlShape != null) _vmlShape.getClientDataArray(0).setRowArray(0, new BigInteger(String.valueOf(row))); } 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 34db7c403..6c13857f9 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -175,9 +175,14 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { initRows(worksheet); columnHelper = new ColumnHelper(worksheet); + // Look for bits we're interested in for(POIXMLDocumentPart p : getRelations()){ - if(p instanceof CommentsTable) sheetComments = (CommentsTable)p; + if(p instanceof CommentsTable) { + sheetComments = (CommentsTable)p; + break; + } } + // Process external hyperlinks for the sheet, if there are any initHyperlinks(); }