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
This commit is contained in:
Nick Burch 2010-06-14 15:43:47 +00:00
parent 9180721741
commit 741f499c4a
4 changed files with 55 additions and 11 deletions

View File

@ -34,6 +34,7 @@
<changes> <changes>
<release version="3.7-beta2" date="2010-??-??"> <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">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> <action dev="POI-DEVELOPERS" type="fix">When formatting numbers with DataFormatter, handle brackets following colours</action>
</release> </release>

View File

@ -19,20 +19,27 @@ package org.apache.poi.xssf.model;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; 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.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.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument; 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 { public class CommentsTable extends POIXMLDocumentPart {
private CTComments comments; 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() { public CommentsTable() {
super(); super();
@ -67,6 +74,17 @@ public class CommentsTable extends POIXMLDocumentPart {
writeTo(out); writeTo(out);
out.close(); 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() { public int getNumberOfComments() {
return comments.getCommentList().sizeOfCommentArray(); return comments.getCommentList().sizeOfCommentArray();
@ -95,18 +113,26 @@ public class CommentsTable extends POIXMLDocumentPart {
} }
public CTComment getCTComment(String cellRef) { public CTComment getCTComment(String cellRef) {
for (CTComment comment : comments.getCommentList().getCommentArray()) { // Create the cache if needed
if (cellRef.equals(comment.getRef())) { if(commentRefs == null) {
return comment; 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() { public CTComment newComment() {
CTComment ct = comments.getCommentList().addNewComment(); CTComment ct = comments.getCommentList().addNewComment();
ct.setRef("A1"); ct.setRef("A1");
ct.setAuthorId(0); ct.setAuthorId(0);
if(commentRefs != null) {
commentRefs.put(ct.getRef(), ct);
}
return ct; return ct;
} }
@ -116,6 +142,10 @@ public class CommentsTable extends POIXMLDocumentPart {
CTComment comment = lst.getCommentArray(i); CTComment comment = lst.getCommentArray(i);
if (cellRef.equals(comment.getRef())) { if (cellRef.equals(comment.getRef())) {
lst.removeComment(i); lst.removeComment(i);
if(commentRefs != null) {
commentRefs.remove(cellRef);
}
return true; return true;
} }
} }

View File

@ -110,8 +110,12 @@ public class XSSFComment implements Comment {
* @param col the 0-based column of the cell that contains the comment * @param col the 0-based column of the cell that contains the comment
*/ */
public void setColumn(int col) { public void setColumn(int col) {
String oldRef = _comment.getRef();
CellReference ref = new CellReference(getRow(), col); 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))); 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 * @param row the 0-based row of the cell that contains the comment
*/ */
public void setRow(int row) { public void setRow(int row) {
String oldRef = _comment.getRef();
String newRef = String newRef =
(new CellReference(row, getColumn())).formatAsString(); (new CellReference(row, getColumn())).formatAsString();
_comment.setRef(newRef); _comment.setRef(newRef);
_comments.referenceUpdated(oldRef, _comment);
if(_vmlShape != null) _vmlShape.getClientDataArray(0).setRowArray(0, new BigInteger(String.valueOf(row))); if(_vmlShape != null) _vmlShape.getClientDataArray(0).setRowArray(0, new BigInteger(String.valueOf(row)));
} }

View File

@ -175,9 +175,14 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
initRows(worksheet); initRows(worksheet);
columnHelper = new ColumnHelper(worksheet); columnHelper = new ColumnHelper(worksheet);
// Look for bits we're interested in
for(POIXMLDocumentPart p : getRelations()){ 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 // Process external hyperlinks for the sheet, if there are any
initHyperlinks(); initHyperlinks();
} }