Bug 577489: Improve xlsx performance in layoutCells() method

Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=577489

Signed-off-by: Denis Nikiforov <denis.nikif@gmail.com>
Change-Id: I0c86f38045185ed012f45c562db992d453b64fed
diff --git a/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/XLSXParser.java b/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/XLSXParser.java
index ba79f9e..100580f 100644
--- a/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/XLSXParser.java
+++ b/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/XLSXParser.java
@@ -358,9 +358,12 @@
 		int maxCol = 0;
 		
 		int curRow = 0;
-    	NodeList rows = getDocument().getElementsByTagName("row");
-		for (int i=0; i<rows.getLength(); i++) {
-			Element row = (Element)rows.item(i);
+		Node sheetData = getDocument().getElementsByTagName("sheetData").item(0);
+		for (Node node = sheetData.getFirstChild(); node != null; node = node.getNextSibling()) {
+			if (!(node instanceof Element)) {
+				continue;
+			}
+			Element row = (Element) node;
 			int rowIndex = Integer.valueOf(row.getAttribute("r"))-1;
 			int rowDiff = getPreviousRowGap(rowIndex);
 			curRow += rowDiff;
diff --git a/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/cellmarkers/AbstractCellMarker.java b/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/cellmarkers/AbstractCellMarker.java
index d208329..aa1843f 100644
--- a/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/cellmarkers/AbstractCellMarker.java
+++ b/plugins/org.eclipse.gendoc.document.parser.xlsx/src/org/eclipse/gendoc/document/parser/xlsx/cellmarkers/AbstractCellMarker.java
@@ -57,11 +57,8 @@
 	public List<CellMark> getAppliedMarks(XLSXParser xlsxParser) {		
 		Set<CellMark> res = new HashSet<CellMark>();
 		try {
-			NodeList refs = XPathXlsxUtils.evaluateNodes(xlsxParser.getDocument(),"//:row/:c/gendoc:mark[@id='"+this.mark+"']");
-			for (int i=0; i<refs.getLength(); i++) {
-				Element markEl = (Element)refs.item(i);				
-				CellMark m = getCellMark(markEl);
-				res.add(m);
+			for (Element cell : getMarkedCells(xlsxParser)) {
+				res.add(getCellMark(cell));
 			}
 		} catch (Exception e) {
 			throw new IllegalArgumentException(e.getMessage(),e);
@@ -128,21 +125,32 @@
 
 	@Override
 	public void cleanup(XLSXParser parser) {
-		try {
-			unmarkCells(parser);
-		} catch (XPathExpressionException e) {
-			throw new RuntimeException(e);
-		}
+		unmarkCells(parser);
 	}
 
-	protected void unmarkCells(XLSXParser xlsxParser) throws XPathExpressionException {
-		NodeList nl = XPathXlsxUtils.evaluateNodes(xlsxParser.getDocument(),"//:row/:c/gendoc:mark[@id='"+mark+"']");
-		for (int i=0; i<nl.getLength(); i++) {
-			Node n = nl.item(i);
-			n.getParentNode().removeChild(n);
+	protected void unmarkCells(XLSXParser xlsxParser) {
+		for (Element cell : getMarkedCells(xlsxParser)) {
+			cell.getParentNode().removeChild(cell);
 		}
 	}
 	
+	private List<Element> getMarkedCells(XLSXParser xlsxParser) {
+		List<Element> res = new ArrayList<Element>();
+		Node sheetData = xlsxParser.getDocument().getElementsByTagName("sheetData").item(0);
+		for (Node row = sheetData.getFirstChild(); row != null; row = row.getNextSibling()) {
+			for (Node cell = row.getFirstChild(); cell != null; cell = cell.getNextSibling()) {
+				for (Node node = cell.getFirstChild(); node != null; node = node.getNextSibling()) {
+					if ("gendoc:mark".equals(node.getNodeName())) {
+						if (mark.equals(((Element) node).getAttribute("id"))) {
+							res.add((Element) node);
+						}
+					}
+				}
+			}
+		}
+		return res;
+	}
+
 	public Element getTargetElement(XLSXParser xlsxParser, CellMark mark) throws IOException, XPathExpressionException {
 		String part = mark.xlPart;
 		String path = mark.path;