--- poi-3.14/org/apache/poi/xssf/model/StylesTable.java 2016-09-19 15:00:01.000000000 -0500 +++ poi-3.14/org/apache/poi/xssf/model/StylesTable.java 2016-09-19 16:12:11.000000000 -0500 @@ -19,6 +19,8 @@ import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS; +import com.google.common.collect.HashBiMap; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -69,11 +71,11 @@ */ public class StylesTable extends POIXMLDocumentPart { private final SortedMap numberFormats = new TreeMap(); - private final List fonts = new ArrayList(); - private final List fills = new ArrayList(); - private final List borders = new ArrayList(); + private final HashBiMap fonts = HashBiMap.create(); + private final HashBiMap fills = HashBiMap.create(); + private final HashBiMap borders = HashBiMap.create(); private final List styleXfs = new ArrayList(); - private final List xfs = new ArrayList(); + private final HashBiMap xfs = HashBiMap.create(); private final List dxfs = new ArrayList(); @@ -173,10 +175,10 @@ // Pass the themes table along to things which need to // know about it, but have already been created by now - for(XSSFFont font : fonts) { + for(XSSFFont font : fonts.values()) { font.setThemesTable(theme); } - for(XSSFCellBorder border : borders) { + for(XSSFCellBorder border : borders.values()) { border.setThemesTable(theme); } } @@ -219,26 +221,29 @@ for (CTFont font : ctfonts.getFontArray()) { // Create the font and save it. Themes Table supplied later XSSFFont f = new XSSFFont(font, idx); - fonts.add(f); + fonts.put(fonts.size(), f); idx++; } } CTFills ctfills = styleSheet.getFills(); if(ctfills != null){ for (CTFill fill : ctfills.getFillArray()) { - fills.add(new XSSFCellFill(fill)); + fills.put(fills.size(), new XSSFCellFill(fill)); } } CTBorders ctborders = styleSheet.getBorders(); if(ctborders != null) { for (CTBorder border : ctborders.getBorderArray()) { - borders.add(new XSSFCellBorder(border)); + borders.put(borders.size(), new XSSFCellBorder(border)); } } CTCellXfs cellXfs = styleSheet.getCellXfs(); - if(cellXfs != null) xfs.addAll(Arrays.asList(cellXfs.getXfArray())); + if(cellXfs != null) { + for (CTXf ctxf : cellXfs.getXfArray()) + xfs.put(xfs.size(), ctxf); + } CTCellStyleXfs cellStyleXfs = styleSheet.getCellStyleXfs(); if(cellStyleXfs != null) styleXfs.addAll(Arrays.asList(cellStyleXfs.getXfArray())); @@ -262,6 +267,7 @@ * @return number format code * @deprecated POI 3.14-beta2. Use {@link #getNumberFormatAt(short)} instead. */ + @Deprecated public String getNumberFormatAt(int idx) { return getNumberFormatAt((short) idx); } @@ -360,7 +366,7 @@ String fmt = numberFormats.remove(index); boolean removed = (fmt != null); if (removed) { - for (final CTXf style : xfs) { + for (final CTXf style : xfs.values()) { if (style.isSetNumFmtId() && style.getNumFmtId() == index) { style.unsetApplyNumberFormat(); style.unsetNumFmtId(); @@ -398,8 +404,8 @@ */ public int putFont(XSSFFont font, boolean forceRegistration) { int idx = -1; - if(!forceRegistration) { - idx = fonts.indexOf(font); + if(!forceRegistration && fonts.containsValue(font)) { + idx = fonts.inverse().get(font); } if (idx != -1) { @@ -407,7 +413,7 @@ } idx = fonts.size(); - fonts.add(font); + fonts.put(idx, font); return idx; } public int putFont(XSSFFont font) { @@ -427,10 +433,10 @@ public int putStyle(XSSFCellStyle style) { CTXf mainXF = style.getCoreXf(); - if(! xfs.contains(mainXF)) { - xfs.add(mainXF); + if(! xfs.containsValue(mainXF)) { + xfs.put(xfs.size(), mainXF); } - return xfs.indexOf(mainXF); + return xfs.inverse().get(mainXF); } public XSSFCellBorder getBorderAt(int idx) { @@ -445,11 +451,11 @@ * @return the index of the added border */ public int putBorder(XSSFCellBorder border) { - int idx = borders.indexOf(border); - if (idx != -1) { + Integer idx = borders.inverse().get(border); + if (idx != null) { return idx; } - borders.add(border); + borders.put(borders.size(), border); border.setThemesTable(theme); return borders.size() - 1; } @@ -458,16 +464,23 @@ return fills.get(idx); } - public List getBorders(){ - return Collections.unmodifiableList(borders); + public List getBorders() { + return this.toList(borders); } - public List getFills(){ - return Collections.unmodifiableList(fills); + public List getFills() { + return this.toList(fills); } - public List getFonts(){ - return Collections.unmodifiableList(fonts); + public List getFonts() { + return this.toList(fonts); + } + + private List toList(HashBiMap map) { + final ArrayList list = new ArrayList(map.size()); + for (int i = 0; i < map.size(); i++) + list.add(map.get(i)); + return Collections.unmodifiableList(list); } public Map getNumberFormats(){ @@ -482,11 +495,11 @@ * @return the index of the added fill */ public int putFill(XSSFCellFill fill) { - int idx = fills.indexOf(fill); - if (idx != -1) { + Integer idx = fills.inverse().get(fill); + if (idx != null) { return idx; } - fills.add(fill); + fills.put(fills.size(), fill); return fills.size() - 1; } @@ -504,13 +517,13 @@ */ @Internal public int putCellXf(CTXf cellXf) { - xfs.add(cellXf); + xfs.put(xfs.size(), cellXf); return xfs.size(); } @Internal public void replaceCellXfAt(int idx, CTXf cellXf) { - xfs.set(idx, cellXf); + xfs.put(idx, cellXf); } @Internal @@ -562,6 +575,7 @@ * For unit testing only * @deprecated POI 3.14 beta 2. Use {@link #getNumDataFormats()} instead. */ + @Deprecated @Internal public int _getNumberFormatSize() { return getNumDataFormats(); @@ -627,7 +641,7 @@ ctFonts.setCount(fonts.size()); CTFont[] ctfnt = new CTFont[fonts.size()]; idx = 0; - for(XSSFFont f : fonts) ctfnt[idx++] = f.getCTFont(); + for(XSSFFont f : this.toList(fonts)) ctfnt[idx++] = f.getCTFont(); ctFonts.setFontArray(ctfnt); styleSheet.setFonts(ctFonts); @@ -639,7 +653,7 @@ ctFills.setCount(fills.size()); CTFill[] ctf = new CTFill[fills.size()]; idx = 0; - for(XSSFCellFill f : fills) ctf[idx++] = f.getCTFill(); + for(XSSFCellFill f : this.toList(fills)) ctf[idx++] = f.getCTFill(); ctFills.setFillArray(ctf); styleSheet.setFills(ctFills); @@ -651,7 +665,7 @@ ctBorders.setCount(borders.size()); CTBorder[] ctb = new CTBorder[borders.size()]; idx = 0; - for(XSSFCellBorder b : borders) ctb[idx++] = b.getCTBorder(); + for(XSSFCellBorder b : this.toList(borders)) ctb[idx++] = b.getCTBorder(); ctBorders.setBorderArray(ctb); styleSheet.setBorders(ctBorders); @@ -663,7 +677,7 @@ } ctXfs.setCount(xfs.size()); ctXfs.setXfArray( - xfs.toArray(new CTXf[xfs.size()]) + this.toList(xfs).toArray(new CTXf[xfs.size()]) ); styleSheet.setCellXfs(ctXfs); } @@ -707,20 +721,20 @@ private void initialize() { //CTFont ctFont = createDefaultFont(); XSSFFont xssfFont = createDefaultFont(); - fonts.add(xssfFont); + fonts.put(fonts.size(), xssfFont); CTFill[] ctFill = createDefaultFills(); - fills.add(new XSSFCellFill(ctFill[0])); - fills.add(new XSSFCellFill(ctFill[1])); + fills.put(fills.size(), new XSSFCellFill(ctFill[0])); + fills.put(fills.size(), new XSSFCellFill(ctFill[1])); CTBorder ctBorder = createDefaultBorder(); - borders.add(new XSSFCellBorder(ctBorder)); + borders.put(borders.size(), new XSSFCellBorder(ctBorder)); CTXf styleXf = createDefaultXf(); styleXfs.add(styleXf); CTXf xf = createDefaultXf(); xf.setXfId(0); - xfs.add(xf); + xfs.put(xfs.size(), xf); } private static CTXf createDefaultXf() { @@ -805,7 +819,7 @@ * Finds a font that matches the one with the supplied attributes */ public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) { - for (XSSFFont font : fonts) { + for (XSSFFont font : fonts.values()) { if ( (font.getBoldweight() == boldWeight) && font.getColor() == color && font.getFontHeight() == fontHeight