ASF Bugzilla – Attachment 36475 Details for
Bug 63234
XSSFFont.equals, hashCode very slow; revised code presented
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
XSSFFont.java revised to speed hashCode, toString, and equals by ~1000
file_63234.txt (text/plain), 20.38 KB, created by
David Gauntt
on 2019-03-05 20:33:35 UTC
(
hide
)
Description:
XSSFFont.java revised to speed hashCode, toString, and equals by ~1000
Filename:
MIME Type:
Creator:
David Gauntt
Created:
2019-03-05 20:33:35 UTC
Size:
20.38 KB
patch
obsolete
>/* ==================================================================== > Licensed to the Apache Software Foundation (ASF) under one or more > contributor license agreements. See the NOTICE file distributed with > this work for additional information regarding copyright ownership. > The ASF licenses this file to You under the Apache License, Version 2.0 > (the "License"); you may not use this file except in compliance with > the License. You may obtain a copy of the License at > > http://www.apache.org/licenses/LICENSE-2.0 > > Unless required by applicable law or agreed to in writing, software > distributed under the License is distributed on an "AS IS" BASIS, > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > See the License for the specific language governing permissions and > limitations under the License. >==================================================================== */ >package org.apache.poi.xssf.usermodel; > >import org.apache.poi.ooxml.POIXMLException; >import org.apache.poi.ss.usermodel.Font; >import org.apache.poi.ss.usermodel.FontCharset; >import org.apache.poi.ss.usermodel.FontFamily; >import org.apache.poi.ss.usermodel.FontScheme; >import org.apache.poi.ss.usermodel.FontUnderline; >import org.apache.poi.ss.usermodel.IndexedColors; >import org.apache.poi.util.Internal; >import org.apache.poi.xssf.model.StylesTable; >import org.apache.poi.xssf.model.ThemesTable; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontName; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontScheme; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIntProperty; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFontScheme; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues; >import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun; > >/** > * Represents a font used in a workbook. > * > * @author Gisella Bronzetti > */ >public class XSSFFont implements Font { > > /** > * By default, Microsoft Office Excel 2007 uses the Calibri font in font > * size 11 > */ > public static final String DEFAULT_FONT_NAME = "Calibri"; > /** > * By default, Microsoft Office Excel 2007 uses the Calibri font in font > * size 11 > */ > public static final short DEFAULT_FONT_SIZE = 11; > /** > * Default font color is black > * > * @see org.apache.poi.ss.usermodel.IndexedColors#BLACK > */ > public static final short DEFAULT_FONT_COLOR = IndexedColors.BLACK.getIndex(); > > private IndexedColorMap _indexedColorMap; > private ThemesTable _themes; > private CTFont _ctFont; > private int _index; > private Integer _hashCode = null; > private String _text = null; > > /** > * Create a new XSSFFont > * > * @param font > * the underlying CTFont bean > */ > @Internal > public XSSFFont(CTFont font) { > _ctFont = font; > _index = 0; > } > > /** > * Called from parsing styles.xml > * > * @param font > * CTFont > * @param index > * font index > * @param colorMap > * for default or custom indexed colors > */ > @Internal > public XSSFFont(CTFont font, int index, IndexedColorMap colorMap) { > _ctFont = font; > _index = (short) index; > _indexedColorMap = colorMap; > } > > /** > * Create a new XSSFont. This method is protected to be used only by > * XSSFWorkbook > */ > public XSSFFont() { > _ctFont = CTFont.Factory.newInstance(); > setFontName(DEFAULT_FONT_NAME); > setFontHeight((double) DEFAULT_FONT_SIZE); > } > > /** > * get the underlying CTFont font > */ > @Internal > public CTFont getCTFont() { > resetHashCode(); // In case the caller changes the contents of _ctFont > return _ctFont; > } > > /** > * get a boolean value for the boldness to use. > * > * @return boolean - bold > */ > @Override > public boolean getBold() { > CTBooleanProperty bold = _ctFont.sizeOfBArray() == 0 ? null : _ctFont.getBArray(0); > return (bold != null && bold.getVal()); > } > > /** > * get character-set to use. > * > * @return int - character-set (0-255) > * @see FontCharset > */ > @Override > public int getCharSet() { > CTIntProperty charset = _ctFont.sizeOfCharsetArray() == 0 ? null : _ctFont.getCharsetArray(0); > return charset == null ? FontCharset.ANSI.getValue() : FontCharset.valueOf(charset.getVal()).getValue(); > } > > /** > * get the indexed color value for the font References a color defined in > * IndexedColors. > * > * @return short - indexed color to use > * @see IndexedColors > */ > @Override > public short getColor() { > CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); > if (color == null) { > return IndexedColors.BLACK.getIndex(); > } > > long index = color.getIndexed(); > if (index == XSSFFont.DEFAULT_FONT_COLOR) { > return IndexedColors.BLACK.getIndex(); > } else if (index == IndexedColors.RED.getIndex()) { > return IndexedColors.RED.getIndex(); > } else { > return (short) index; > } > } > > /** > * get the color value for the font References a color defined as Standard > * Alpha Red Green Blue color value (ARGB). > * > * @return XSSFColor - rgb color to use > */ > public XSSFColor getXSSFColor() { > CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); > if (ctColor != null) { > XSSFColor color = XSSFColor.from(ctColor, _indexedColorMap); > if (_themes != null) { > _themes.inheritFromThemeAsRequired(color); > } > return color; > } else { > return null; > } > } > > /** > * get the color value for the font References a color defined in theme. > * > * @return short - theme defined to use > */ > public short getThemeColor() { > CTColor color = _ctFont.sizeOfColorArray() == 0 ? null : _ctFont.getColorArray(0); > long index = color == null ? 0 : color.getTheme(); > return (short) index; > } > > /** > * Get the font height in unit's of 1/20th of a point. > * <p> > * For many users, the related {@link #getFontHeightInPoints()} will be more > * helpful, as that returns font heights in the more familiar points units, > * eg 10, 12, 14. > * > * @return short - height in 1/20ths of a point > * @see #getFontHeightInPoints() > */ > @Override > public short getFontHeight() { > return (short) (getFontHeightRaw() * 20); > } > > /** > * Get the font height in points. > * <p> > * This will return the same font height that is shown in Excel, such as 10 > * or 14 or 28. > * > * @return short - height in the familiar unit of measure - points > * @see #getFontHeight() > */ > @Override > public short getFontHeightInPoints() { > return (short) getFontHeightRaw(); > } > > /** > * Return the raw font height, in points, but also including fractions. > */ > private double getFontHeightRaw() { > CTFontSize size = _ctFont.sizeOfSzArray() == 0 ? null : _ctFont.getSzArray(0); > if (size != null) { > return size.getVal(); > } > return DEFAULT_FONT_SIZE; > } > > /** > * get the name of the font (i.e. Arial) > * > * @return String - a string representing the name of the font to use > */ > @Override > public String getFontName() { > CTFontName name = _ctFont.sizeOfNameArray() == 0 ? null : _ctFont.getNameArray(0); > return name == null ? DEFAULT_FONT_NAME : name.getVal(); > } > > /** > * get a boolean value that specify whether to use italics or not > * > * @return boolean - value for italic > */ > @Override > public boolean getItalic() { > CTBooleanProperty italic = _ctFont.sizeOfIArray() == 0 ? null : _ctFont.getIArray(0); > return italic != null && italic.getVal(); > } > > /** > * get a boolean value that specify whether to use a strikeout horizontal > * line through the text or not > * > * @return boolean - value for strikeout > */ > @Override > public boolean getStrikeout() { > CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? null : _ctFont.getStrikeArray(0); > return strike != null && strike.getVal(); > } > > /** > * get normal,super or subscript. > * > * @return short - offset type to use (none,super,sub) > * @see Font#SS_NONE > * @see Font#SS_SUPER > * @see Font#SS_SUB > */ > @Override > public short getTypeOffset() { > CTVerticalAlignFontProperty vAlign = _ctFont.sizeOfVertAlignArray() == 0 ? null : _ctFont.getVertAlignArray(0); > if (vAlign == null) { > return Font.SS_NONE; > } > int val = vAlign.getVal().intValue(); > switch (val) { > case STVerticalAlignRun.INT_BASELINE: > return Font.SS_NONE; > case STVerticalAlignRun.INT_SUBSCRIPT: > return Font.SS_SUB; > case STVerticalAlignRun.INT_SUPERSCRIPT: > return Font.SS_SUPER; > default: > throw new POIXMLException("Wrong offset value " + val); > } > } > > /** > * get type of text underlining to use > * > * @return byte - underlining type > * @see org.apache.poi.ss.usermodel.FontUnderline > */ > @Override > public byte getUnderline() { > CTUnderlineProperty underline = _ctFont.sizeOfUArray() == 0 ? null : _ctFont.getUArray(0); > if (underline != null) { > FontUnderline val = FontUnderline.valueOf(underline.getVal().intValue()); > return val.getByteValue(); > } > return Font.U_NONE; > } > > /** > * set a boolean value for the boldness to use. If omitted, the default > * value is true. > * > * @param bold > * - boldness to use > */ > @Override > public void setBold(boolean bold) { > if (bold) { > CTBooleanProperty ctBold = _ctFont.sizeOfBArray() == 0 ? _ctFont.addNewB() : _ctFont.getBArray(0); > ctBold.setVal(true); > } else { > _ctFont.setBArray(null); > } > resetHashCode(); > } > > /** > * set character-set to use. > * > * @param charset > * - charset > * @see FontCharset > */ > @Override > public void setCharSet(byte charset) { > int cs = charset & 0xff; > setCharSet(cs); > } > > /** > * set character-set to use. > * > * @param charset > * - charset > * @see FontCharset > */ > @Override > public void setCharSet(int charset) { > FontCharset fontCharset = FontCharset.valueOf(charset); > if (fontCharset != null) { > setCharSet(fontCharset); > } else { > throw new POIXMLException("Attention: an attempt to set a type of unknow charset and charset"); > } > } > > /** > * set character-set to use. > * > * @param charSet > */ > public void setCharSet(FontCharset charSet) { > CTIntProperty charsetProperty; > if (_ctFont.sizeOfCharsetArray() == 0) { > charsetProperty = _ctFont.addNewCharset(); > } else { > charsetProperty = _ctFont.getCharsetArray(0); > } > // We know that FontCharset only has valid entries in it, > // so we can just set the int value from it > charsetProperty.setVal(charSet.getValue()); > resetHashCode(); > } > > /** > * set the indexed color for the font > * > * @param color > * - color to use > * @see #DEFAULT_FONT_COLOR - Note: default font color > * @see IndexedColors > */ > @Override > public void setColor(short color) { > CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); > switch (color) { > case Font.COLOR_NORMAL: { > ctColor.setIndexed(XSSFFont.DEFAULT_FONT_COLOR); > break; > } > case Font.COLOR_RED: { > ctColor.setIndexed(IndexedColors.RED.getIndex()); > break; > } > default: > ctColor.setIndexed(color); > } > resetHashCode(); > } > > /** > * set the color for the font in Standard Alpha Red Green Blue color value > * > * @param color > * - color to use > */ > public void setColor(XSSFColor color) { > if (color == null) { > _ctFont.setColorArray(null); > } else { > CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); > if (ctColor.isSetIndexed()) { > ctColor.unsetIndexed(); > } > ctColor.setRgb(color.getRGB()); > } > resetHashCode(); > } > > /** > * set the font height in points. > * > * @param height > * - height in points > */ > @Override > public void setFontHeight(short height) { > setFontHeight((double) height / 20); > } > > /** > * set the font height in points. > * > * @param height > * - height in points > */ > public void setFontHeight(double height) { > CTFontSize fontSize = _ctFont.sizeOfSzArray() == 0 ? _ctFont.addNewSz() : _ctFont.getSzArray(0); > fontSize.setVal(height); > resetHashCode(); > } > > /** > * set the font height in points. > * > * @see #setFontHeight > */ > @Override > public void setFontHeightInPoints(short height) { > setFontHeight((double) height); > } > > /** > * set the theme color for the font to use > * > * @param theme > * - theme color to use > */ > public void setThemeColor(short theme) { > CTColor ctColor = _ctFont.sizeOfColorArray() == 0 ? _ctFont.addNewColor() : _ctFont.getColorArray(0); > ctColor.setTheme(theme); > resetHashCode(); > } > > /** > * set the name for the font (i.e. Arial). If the font doesn't exist > * (because it isn't installed on the system), or the charset is invalid for > * that font, then another font should be substituted. The string length for > * this attribute shall be 0 to 31 characters. Default font name is Calibri. > * > * @param name > * - value representing the name of the font to use > * @see #DEFAULT_FONT_NAME > */ > @Override > public void setFontName(String name) { > CTFontName fontName = _ctFont.sizeOfNameArray() == 0 ? _ctFont.addNewName() : _ctFont.getNameArray(0); > fontName.setVal(name == null ? DEFAULT_FONT_NAME : name); > resetHashCode(); > } > > /** > * set a boolean value for the property specifying whether to use italics or > * not If omitted, the default value is true. > * > * @param italic > * - value for italics or not > */ > @Override > public void setItalic(boolean italic) { > if (italic) { > CTBooleanProperty bool = _ctFont.sizeOfIArray() == 0 ? _ctFont.addNewI() : _ctFont.getIArray(0); > bool.setVal(true); > } else { > _ctFont.setIArray(null); > } > resetHashCode(); > } > > /** > * set a boolean value for the property specifying whether to use a > * strikeout horizontal line through the text or not If omitted, the default > * value is true. > * > * @param strikeout > * - value for strikeout or not > */ > @Override > public void setStrikeout(boolean strikeout) { > if (strikeout) { > CTBooleanProperty strike = _ctFont.sizeOfStrikeArray() == 0 ? _ctFont.addNewStrike() > : _ctFont.getStrikeArray(0); > strike.setVal(true); > } else { > _ctFont.setStrikeArray(null); > } > resetHashCode(); > } > > /** > * set normal,super or subscript, that representing the vertical-alignment > * setting. Setting this to either subscript or superscript shall make the > * font size smaller if a smaller font size is available. > * > * @param offset > * - offset type to use (none,super,sub) > * @see #SS_NONE > * @see #SS_SUPER > * @see #SS_SUB > */ > @Override > public void setTypeOffset(short offset) { > if (offset == Font.SS_NONE) { > _ctFont.setVertAlignArray(null); > } else { > CTVerticalAlignFontProperty offsetProperty = _ctFont.sizeOfVertAlignArray() == 0 ? _ctFont.addNewVertAlign() > : _ctFont.getVertAlignArray(0); > switch (offset) { > case Font.SS_NONE: > offsetProperty.setVal(STVerticalAlignRun.BASELINE); > break; > case Font.SS_SUB: > offsetProperty.setVal(STVerticalAlignRun.SUBSCRIPT); > break; > case Font.SS_SUPER: > offsetProperty.setVal(STVerticalAlignRun.SUPERSCRIPT); > break; > default: > throw new IllegalStateException("Invalid type offset: " + offset); > } > } > resetHashCode(); > } > > /** > * set the style of underlining that is used. The none style is equivalent > * to not using underlining at all. > * > * @param underline > * - underline type to use > * @see FontUnderline > */ > @Override > public void setUnderline(byte underline) { > setUnderline(FontUnderline.valueOf(underline)); > } > > /** > * set an enumeration representing the style of underlining that is used. > * The none style is equivalent to not using underlining at all. The > * possible values for this attribute are defined by the FontUnderline > * > * @param underline > * - FontUnderline enum value > */ > public void setUnderline(FontUnderline underline) { > if (underline == FontUnderline.NONE && _ctFont.sizeOfUArray() > 0) { > _ctFont.setUArray(null); > } else { > CTUnderlineProperty ctUnderline = _ctFont.sizeOfUArray() == 0 ? _ctFont.addNewU() : _ctFont.getUArray(0); > STUnderlineValues.Enum val = STUnderlineValues.Enum.forInt(underline.getValue()); > ctUnderline.setVal(val); > } > resetHashCode(); > } > > @Override > public String toString() { > if (_hashCode == null) { > updateHashCode(); > } > return _text; > } > > /** > * Perform a registration of ourselves to the style table > */ > public long registerTo(StylesTable styles) { > _themes = styles.getTheme(); > _index = styles.putFont(this, true); > return _index; > } > > /** > * Records the Themes Table that is associated with the current font, used > * when looking up theme based colours and properties. > */ > public void setThemesTable(ThemesTable themes) { > _themes = themes; > } > > /** > * get the font scheme property. is used only in StylesTable to create the > * default instance of font > * > * @return FontScheme > * @see org.apache.poi.xssf.model.StylesTable#createDefaultFont() > */ > public FontScheme getScheme() { > CTFontScheme scheme = _ctFont.sizeOfSchemeArray() == 0 ? null : _ctFont.getSchemeArray(0); > return scheme == null ? FontScheme.NONE : FontScheme.valueOf(scheme.getVal().intValue()); > } > > /** > * set font scheme property > * > * @param scheme > * - FontScheme enum value > * @see FontScheme > */ > public void setScheme(FontScheme scheme) { > CTFontScheme ctFontScheme = _ctFont.sizeOfSchemeArray() == 0 ? _ctFont.addNewScheme() > : _ctFont.getSchemeArray(0); > STFontScheme.Enum val = STFontScheme.Enum.forInt(scheme.getValue()); > ctFontScheme.setVal(val); > resetHashCode(); > } > > /** > * get the font family to use. > * > * @return the font family to use > * @see org.apache.poi.ss.usermodel.FontFamily > */ > public int getFamily() { > CTIntProperty family = _ctFont.sizeOfFamilyArray() == 0 ? null : _ctFont.getFamilyArray(0); > return family == null ? FontFamily.NOT_APPLICABLE.getValue() : FontFamily.valueOf(family.getVal()).getValue(); > } > > /** > * Set the font family this font belongs to. A font family is a set of fonts > * having common stroke width and serif characteristics. The font name > * overrides when there are conflicting values. > * > * @param value > * - font family > * @see FontFamily > */ > public void setFamily(int value) { > CTIntProperty family = _ctFont.sizeOfFamilyArray() == 0 ? _ctFont.addNewFamily() : _ctFont.getFamilyArray(0); > family.setVal(value); > resetHashCode(); > } > > /** > * set an enumeration representing the font family this font belongs to. A > * font family is a set of fonts having common stroke width and serif > * characteristics. > * > * @param family > * font family > * @see #setFamily(int value) > */ > public void setFamily(FontFamily family) { > setFamily(family.getValue()); > } > > @Override > @Deprecated > public short getIndex() { > return (short) getIndexAsInt(); > } > > @Override > public int getIndexAsInt() { > return _index; > } > > private void resetHashCode() { > _text = null; > _hashCode = null; > } > > private void updateHashCode() { > _text = _ctFont.toString(); > _hashCode = _ctFont.toString().hashCode(); > } > > public int oldHashCode() { > return _ctFont.toString().hashCode(); > } > > public boolean oldEquals(Object o) { > if (!(o instanceof XSSFFont)) { > return false; > } > > XSSFFont cf = (XSSFFont) o; > return _ctFont.toString().equals(cf.getCTFont().toString()); > } > > @Override > public int hashCode() { > if (_hashCode == null) { > updateHashCode(); > } > return _hashCode; > } > > @Override > public boolean equals(Object o) { > if (this == o) { > return true; > } > if (!(o instanceof XSSFFont)) { > return false; > } > > if (_hashCode != o.hashCode()) { > return false; > } > > XSSFFont cf = (XSSFFont) o; > return toString().equals(cf.toString()); > } > >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 63234
:
36475
|
36483
|
36487