mirror of https://github.com/apache/poi.git
Sonar fixes - type: bugs / severity: major
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1871064 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
82156bc63c
commit
0f29ae8e4d
|
@ -685,8 +685,8 @@ public class AddDimensionedImage {
|
|||
if(sheet instanceof HSSFSheet) {
|
||||
// Next, from the columns width, calculate how many co-ordinate
|
||||
// positons there are per millimetre
|
||||
coordinatePositionsPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
|
||||
colWidthMM;
|
||||
coordinatePositionsPerMM = (colWidthMM == 0) ? 0
|
||||
: ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / colWidthMM;
|
||||
// From this figure, determine how many co-ordinat positions to
|
||||
// inset the left hand or bottom edge of the image.
|
||||
inset = (int)(coordinatePositionsPerMM * overlapMM);
|
||||
|
@ -784,8 +784,8 @@ public class AddDimensionedImage {
|
|||
}
|
||||
|
||||
if(sheet instanceof HSSFSheet) {
|
||||
rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
|
||||
rowHeightMM;
|
||||
rowCoordinatesPerMM = (rowHeightMM == 0) ? 0
|
||||
: ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / rowHeightMM;
|
||||
inset = (int)(overlapMM * rowCoordinatesPerMM);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -17,15 +17,26 @@
|
|||
|
||||
package org.apache.poi.ss.examples;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.*;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Calendar;
|
||||
import java.io.FileOutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.BorderStyle;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.DataFormat;
|
||||
import org.apache.poi.ss.usermodel.FillPatternType;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||
import org.apache.poi.ss.usermodel.PrintSetup;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
/**
|
||||
* A business plan demo
|
||||
|
@ -36,8 +47,6 @@ import java.text.SimpleDateFormat;
|
|||
*/
|
||||
public class BusinessPlan {
|
||||
|
||||
private static SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM");
|
||||
|
||||
private static final String[] titles = {
|
||||
"ID", "Project Name", "Owner", "Days", "Start", "End"};
|
||||
|
||||
|
@ -84,6 +93,8 @@ public class BusinessPlan {
|
|||
if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook();
|
||||
else wb = new XSSFWorkbook();
|
||||
|
||||
final SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM");
|
||||
|
||||
Map<String, CellStyle> styles = createStyles(wb);
|
||||
|
||||
Sheet sheet = wb.createSheet("Business Plan");
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.HexDump;
|
||||
|
@ -30,7 +32,8 @@ import org.apache.poi.util.StringUtil;
|
|||
* REFERENCE: PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
|
||||
*/
|
||||
public final class FontRecord extends StandardRecord {
|
||||
public final static short sid = 0x0031; // docs are wrong (0x231 Microsoft Support site article Q184647)
|
||||
// docs are wrong (0x231 Microsoft Support site article Q184647)
|
||||
public final static short sid = 0x0031;
|
||||
public final static short SS_NONE = 0;
|
||||
public final static short SS_SUPER = 1;
|
||||
public final static short SS_SUB = 2;
|
||||
|
@ -39,7 +42,8 @@ public final class FontRecord extends StandardRecord {
|
|||
public final static byte U_DOUBLE = 2;
|
||||
public final static byte U_SINGLE_ACCOUNTING = 0x21;
|
||||
public final static byte U_DOUBLE_ACCOUNTING = 0x22;
|
||||
private short field_1_font_height; // in units of .05 of a point
|
||||
// in units of .05 of a point
|
||||
private short field_1_font_height;
|
||||
private short field_2_attributes;
|
||||
|
||||
// 0 0x01 - Reserved bit must be 0
|
||||
|
@ -359,24 +363,22 @@ public final class FontRecord extends StandardRecord {
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("[FONT]\n");
|
||||
sb.append(" .fontheight = ").append(HexDump.shortToHex(getFontHeight())).append("\n");
|
||||
sb.append(" .attributes = ").append(HexDump.shortToHex(getAttributes())).append("\n");
|
||||
sb.append(" .italic = ").append(isItalic()).append("\n");
|
||||
sb.append(" .strikout = ").append(isStruckout()).append("\n");
|
||||
sb.append(" .macoutlined= ").append(isMacoutlined()).append("\n");
|
||||
sb.append(" .macshadowed= ").append(isMacshadowed()).append("\n");
|
||||
sb.append(" .colorpalette = ").append(HexDump.shortToHex(getColorPaletteIndex())).append("\n");
|
||||
sb.append(" .boldweight = ").append(HexDump.shortToHex(getBoldWeight())).append("\n");
|
||||
sb.append(" .supersubscript= ").append(HexDump.shortToHex(getSuperSubScript())).append("\n");
|
||||
sb.append(" .underline = ").append(HexDump.byteToHex(getUnderline())).append("\n");
|
||||
sb.append(" .family = ").append(HexDump.byteToHex(getFamily())).append("\n");
|
||||
sb.append(" .charset = ").append(HexDump.byteToHex(getCharset())).append("\n");
|
||||
sb.append(" .fontname = ").append(getFontName()).append("\n");
|
||||
sb.append("[/FONT]\n");
|
||||
return sb.toString();
|
||||
return
|
||||
"[FONT]\n" +
|
||||
" .fontheight = " + HexDump.shortToHex(getFontHeight()) + "\n" +
|
||||
" .attributes = " + HexDump.shortToHex(getAttributes()) + "\n" +
|
||||
" .italic = " + isItalic() + "\n" +
|
||||
" .strikout = " + isStruckout() + "\n" +
|
||||
" .macoutlined= " + isMacoutlined() + "\n" +
|
||||
" .macshadowed= " + isMacshadowed() + "\n" +
|
||||
" .colorpalette = " + HexDump.shortToHex(getColorPaletteIndex()) + "\n" +
|
||||
" .boldweight = " + HexDump.shortToHex(getBoldWeight()) + "\n" +
|
||||
" .supersubscript= " + HexDump.shortToHex(getSuperSubScript()) + "\n" +
|
||||
" .underline = " + HexDump.byteToHex(getUnderline()) + "\n" +
|
||||
" .family = " + HexDump.byteToHex(getFamily()) + "\n" +
|
||||
" .charset = " + HexDump.byteToHex(getCharset()) + "\n" +
|
||||
" .fontname = " + getFontName() + "\n" +
|
||||
"[/FONT]\n";
|
||||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
|
@ -470,6 +472,7 @@ public final class FontRecord extends StandardRecord {
|
|||
* @return true, if the properties match
|
||||
*/
|
||||
public boolean sameProperties(FontRecord other) {
|
||||
|
||||
return
|
||||
field_1_font_height == other.field_1_font_height &&
|
||||
field_2_attributes == other.field_2_attributes &&
|
||||
|
@ -480,15 +483,11 @@ public final class FontRecord extends StandardRecord {
|
|||
field_7_family == other.field_7_family &&
|
||||
field_8_charset == other.field_8_charset &&
|
||||
field_9_zero == other.field_9_zero &&
|
||||
stringEquals(this.field_11_font_name, other.field_11_font_name)
|
||||
Objects.equals(this.field_11_font_name, other.field_11_font_name)
|
||||
;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof FontRecord) ? sameProperties((FontRecord)o) : false;
|
||||
}
|
||||
|
||||
private static boolean stringEquals(String s1, String s2) {
|
||||
return (s1 == s2 || (s1 != null && s1.equals(s2)));
|
||||
return (o instanceof FontRecord) && sameProperties((FontRecord) o);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -836,8 +836,8 @@ public final class HSSFCellStyle implements CellStyle {
|
|||
if(_workbook != source._workbook) {
|
||||
|
||||
lastDateFormat.set(Short.MIN_VALUE);
|
||||
lastFormats.set(null);
|
||||
getDataFormatStringCache.set(null);
|
||||
lastFormats.remove();
|
||||
getDataFormatStringCache.remove();
|
||||
|
||||
// Then we need to clone the format string,
|
||||
// and update the format record for this
|
||||
|
|
|
@ -21,10 +21,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
import javax.crypto.ShortBufferException;
|
||||
|
||||
import org.apache.poi.EncryptedDocumentException;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
|
@ -82,7 +79,7 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream {
|
|||
@Override
|
||||
public int read() throws IOException {
|
||||
byte[] b = { 0 };
|
||||
return (read(b) == 1) ? b[0] : -1;
|
||||
return (read(b) == 1) ? (b[0] & 0xFF) : -1;
|
||||
}
|
||||
|
||||
// do not implement! -> recursion
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
==================================================================== */
|
||||
package org.apache.poi.poifs.crypt;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.DigestException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Key;
|
||||
|
@ -44,11 +44,14 @@ import org.apache.poi.util.StringUtil;
|
|||
* Helper functions used for standard and agile encryption
|
||||
*/
|
||||
@Internal
|
||||
public class CryptoFunctions {
|
||||
public final class CryptoFunctions {
|
||||
|
||||
//arbitrarily selected; may need to increase
|
||||
private static final int MAX_RECORD_LENGTH = 100_000;
|
||||
|
||||
private CryptoFunctions() {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p><cite>2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)<br>
|
||||
* 2.3.4.11 Encryption Key Generation (Agile Encryption)</cite></p>
|
||||
|
@ -78,10 +81,10 @@ public class CryptoFunctions {
|
|||
*
|
||||
* <p>For POI, H_final will be calculated by {@link #generateKey(byte[],HashAlgorithm,byte[],int)}</p>
|
||||
*
|
||||
* @param password
|
||||
* @param hashAlgorithm
|
||||
* @param salt
|
||||
* @param spinCount
|
||||
* @param password the password
|
||||
* @param hashAlgorithm the hash algorithm
|
||||
* @param salt the initial salt value
|
||||
* @param spinCount the repetition count
|
||||
* @return the hashed password
|
||||
*/
|
||||
public static byte[] hashPassword(String password, HashAlgorithm hashAlgorithm, byte[] salt, int spinCount) {
|
||||
|
@ -93,10 +96,10 @@ public class CryptoFunctions {
|
|||
* The difference is, read protection uses the order iterator then hash in the hash loop, whereas write protection
|
||||
* uses first the last hash value and then the current iterator value
|
||||
*
|
||||
* @param password
|
||||
* @param hashAlgorithm
|
||||
* @param salt
|
||||
* @param spinCount
|
||||
* @param password the pasword
|
||||
* @param hashAlgorithm the hash algorighm
|
||||
* @param salt the initial salt value
|
||||
* @param spinCount the repetition count
|
||||
* @param iteratorFirst if true, the iterator is hashed before the n-1 hash value,
|
||||
* if false the n-1 hash value is applied first
|
||||
* @return the hashed password
|
||||
|
@ -174,10 +177,10 @@ public class CryptoFunctions {
|
|||
* MUST be padded by appending bytes with a value of 0x36. If the hash value is larger in size than
|
||||
* PasswordKeyEncryptor.keyBits, the key is obtained by truncating the hash value.</p>
|
||||
*
|
||||
* @param passwordHash
|
||||
* @param hashAlgorithm
|
||||
* @param blockKey
|
||||
* @param keySize
|
||||
* @param passwordHash the hashed password byte
|
||||
* @param hashAlgorithm the hash algorithm
|
||||
* @param blockKey the block key
|
||||
* @param keySize the key size
|
||||
* @return intermediate key
|
||||
*/
|
||||
public static byte[] generateKey(byte[] passwordHash, HashAlgorithm hashAlgorithm, byte[] blockKey, int keySize) {
|
||||
|
@ -198,7 +201,6 @@ public class CryptoFunctions {
|
|||
* @param vec the initialization vector (IV), can be null
|
||||
* @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE
|
||||
* @return the requested cipher
|
||||
* @throws GeneralSecurityException
|
||||
* @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified,
|
||||
* which depends on a missing bouncy castle provider
|
||||
*/
|
||||
|
@ -218,7 +220,6 @@ public class CryptoFunctions {
|
|||
* @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE
|
||||
* @param padding the padding (null = NOPADDING, ANSIX923Padding, PKCS5Padding, PKCS7Padding, ISO10126Padding, ...)
|
||||
* @return the requested cipher
|
||||
* @throws GeneralSecurityException
|
||||
* @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified,
|
||||
* which depends on a missing bouncy castle provider
|
||||
*/
|
||||
|
@ -442,12 +443,13 @@ public class CryptoFunctions {
|
|||
// --> For every bit in the character, starting with the least significant and progressing to (but excluding)
|
||||
// the most significant, if the bit is set, XOR the keys high-order word with the corresponding word from
|
||||
// the Encryption Matrix
|
||||
for (int i = 0; i < arrByteChars.length; i++) {
|
||||
int tmp = maxPasswordLength - arrByteChars.length + i;
|
||||
for (int intBit = 0; intBit < 7; intBit++) {
|
||||
if ((arrByteChars[i] & (0x0001 << intBit)) != 0) {
|
||||
highOrderWord ^= ENCRYPTION_MATRIX[tmp][intBit];
|
||||
int line = maxPasswordLength - arrByteChars.length;
|
||||
for (byte ch : arrByteChars) {
|
||||
for (int xor : ENCRYPTION_MATRIX[line++]) {
|
||||
if ((ch & 1) == 1) {
|
||||
highOrderWord ^= xor;
|
||||
}
|
||||
ch >>>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,7 +482,7 @@ public class CryptoFunctions {
|
|||
int hashedPassword = createXorVerifier2(password);
|
||||
|
||||
return String.format(Locale.ROOT, "%1$02X%2$02X%3$02X%4$02X"
|
||||
, ( hashedPassword >>> 0 ) & 0xFF
|
||||
, (hashedPassword) & 0xFF
|
||||
, ( hashedPassword >>> 8 ) & 0xFF
|
||||
, ( hashedPassword >>> 16 ) & 0xFF
|
||||
, ( hashedPassword >>> 24 ) & 0xFF
|
||||
|
@ -515,7 +517,7 @@ public class CryptoFunctions {
|
|||
if (password.length() > 15) {
|
||||
password = password.substring(0, 15);
|
||||
}
|
||||
byte[] passBytes = password.getBytes(Charset.forName("ASCII"));
|
||||
byte[] passBytes = password.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
// this code is based on the libre office implementation.
|
||||
// The MS-OFFCRYPTO misses some infos about the various rotation sizes
|
||||
|
|
|
@ -60,7 +60,7 @@ import org.apache.poi.util.Internal;
|
|||
} catch (ShortBufferException e) {
|
||||
throw new EncryptedDocumentException(e);
|
||||
}
|
||||
return oneByte[0];
|
||||
return oneByte[0] & 0xFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,7 +51,7 @@ import org.apache.poi.util.Internal;
|
|||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
public synchronized void write(int b) {
|
||||
try {
|
||||
oneByte[0] = (byte)b;
|
||||
cipher.update(oneByte, 0, 1, oneByte, 0);
|
||||
|
@ -62,7 +62,7 @@ import org.apache.poi.util.Internal;
|
|||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) {
|
||||
public synchronized void write(byte[] b, int off, int len) {
|
||||
try {
|
||||
cipher.update(b, off, len, b, off);
|
||||
super.write(b, off, len);
|
||||
|
|
|
@ -146,7 +146,7 @@ public final class DocumentInputStream extends InputStream implements LittleEndi
|
|||
}
|
||||
|
||||
@Override
|
||||
public void mark(int ignoredReadlimit) {
|
||||
public synchronized void mark(int ignoredReadlimit) {
|
||||
_marked_offset = _current_offset;
|
||||
_marked_offset_count = Math.max(0, _current_block_count - 1);
|
||||
}
|
||||
|
@ -159,13 +159,7 @@ public final class DocumentInputStream extends InputStream implements LittleEndi
|
|||
}
|
||||
byte[] b = new byte[1];
|
||||
int result = read(b, 0, 1);
|
||||
if(result >= 0) {
|
||||
if(b[0] < 0) {
|
||||
return b[0]+256;
|
||||
}
|
||||
return b[0];
|
||||
}
|
||||
return result;
|
||||
return (result == EOF) ? EOF : (b[0] & 0xFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -199,7 +193,7 @@ public final class DocumentInputStream extends InputStream implements LittleEndi
|
|||
* method repositions the stream to its beginning.
|
||||
*/
|
||||
@Override
|
||||
public void reset() {
|
||||
public synchronized void reset() {
|
||||
// Special case for reset to the start
|
||||
if(_marked_offset == 0 && _marked_offset_count == 0) {
|
||||
_current_block_count = _marked_offset_count;
|
||||
|
|
|
@ -47,11 +47,15 @@ public class DrawFactory {
|
|||
* This is a fallback, for operations where usercode can't set a graphics context.
|
||||
* Preferably use the rendering hint {@link Drawable#DRAW_FACTORY} to set the factory.
|
||||
*
|
||||
* @param factory the custom factory
|
||||
* @param factory the custom factory or {@code null} to reset/remove the default factory
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static void setDefaultFactory(DrawFactory factory) {
|
||||
defaultFactory.set(factory);
|
||||
if (factory == null) {
|
||||
defaultFactory.remove();
|
||||
} else {
|
||||
defaultFactory.set(factory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,56 +60,52 @@ public class DrawShape implements Drawable {
|
|||
return;
|
||||
}
|
||||
|
||||
final PlaceableShape<?,?> ps = (PlaceableShape<?,?>)shape;
|
||||
final boolean isHSLF = isHSLF(shape);
|
||||
final Rectangle2D anchor = getAnchor(graphics, (PlaceableShape<?,?>)shape);
|
||||
if (anchor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Rectangle2D anchor = getAnchor(graphics, ps);
|
||||
|
||||
char[] cmds = isHSLF ? new char[]{'h', 'v', 'r'} : new char[]{'r', 'h', 'v'};
|
||||
for (char ch : cmds) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
//flip horizontal
|
||||
if (ps.getFlipHorizontal()) {
|
||||
graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
|
||||
graphics.scale(-1, 1);
|
||||
graphics.translate(-anchor.getX(), -anchor.getY());
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
//flip vertical
|
||||
if (ps.getFlipVertical()) {
|
||||
graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
|
||||
graphics.scale(1, -1);
|
||||
graphics.translate(-anchor.getX(), -anchor.getY());
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
// rotation
|
||||
double rotation = ps.getRotation();
|
||||
if (rotation != 0.) {
|
||||
// PowerPoint rotates shapes relative to the geometric center
|
||||
double centerX = anchor.getCenterX();
|
||||
double centerY = anchor.getCenterY();
|
||||
|
||||
|
||||
// transformation is applied reversed ...
|
||||
graphics.translate(centerX, centerY);
|
||||
graphics.rotate(Math.toRadians(rotation));
|
||||
graphics.translate(-centerX, -centerY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("unexpected transform code " + ch);
|
||||
}
|
||||
if (isHSLF(shape)) {
|
||||
flipHorizontal(graphics, anchor);
|
||||
flipVertical(graphics, anchor);
|
||||
rotate(graphics, anchor);
|
||||
} else {
|
||||
rotate(graphics, anchor);
|
||||
flipHorizontal(graphics, anchor);
|
||||
flipVertical(graphics, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
private static double safeScale(double dim1, double dim2) {
|
||||
if (dim1 == 0.) {
|
||||
return 1;
|
||||
private void flipHorizontal(Graphics2D graphics, Rectangle2D anchor) {
|
||||
assert(shape instanceof PlaceableShape && anchor != null);
|
||||
if (((PlaceableShape<?,?>)shape).getFlipHorizontal()) {
|
||||
graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
|
||||
graphics.scale(-1, 1);
|
||||
graphics.translate(-anchor.getX(), -anchor.getY());
|
||||
}
|
||||
return (dim2 == 0.) ? 1 : dim1/dim2;
|
||||
}
|
||||
|
||||
private void flipVertical(Graphics2D graphics, Rectangle2D anchor) {
|
||||
assert(shape instanceof PlaceableShape && anchor != null);
|
||||
if (((PlaceableShape<?,?>)shape).getFlipVertical()) {
|
||||
graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
|
||||
graphics.scale(1, -1);
|
||||
graphics.translate(-anchor.getX(), -anchor.getY());
|
||||
}
|
||||
}
|
||||
|
||||
private void rotate(Graphics2D graphics, Rectangle2D anchor) {
|
||||
assert(shape instanceof PlaceableShape && anchor != null);
|
||||
double rotation = ((PlaceableShape<?,?>)shape).getRotation();
|
||||
if (rotation != 0.) {
|
||||
// PowerPoint rotates shapes relative to the geometric center
|
||||
graphics.rotate(Math.toRadians(rotation), anchor.getCenterX(), anchor.getCenterY());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static double safeScale(double dim1, double dim2) {
|
||||
return (dim1 == 0. || dim2 == 0.) ? 1 : dim1/dim2;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -160,15 +156,11 @@ public class DrawShape implements Drawable {
|
|||
// this handling is only based on try and error ... not sure why h/xslf is handled differently.
|
||||
|
||||
if (!isHSLF) {
|
||||
txs2.translate(centerX, centerY);
|
||||
txs2.quadrantRotate(1);
|
||||
txs2.translate(-centerX, -centerY);
|
||||
txs2.quadrantRotate(1, centerX, centerY);
|
||||
txs2.concatenate(tx);
|
||||
}
|
||||
|
||||
txs2.translate(centerX, centerY);
|
||||
txs2.quadrantRotate(3);
|
||||
txs2.translate(-centerX, -centerY);
|
||||
txs2.quadrantRotate(3, centerX, centerY);
|
||||
|
||||
if (isHSLF) {
|
||||
txs2.concatenate(tx);
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
package org.apache.poi.ss.formula.functions;
|
||||
|
||||
import org.apache.poi.ss.formula.OperationEvaluationContext;
|
||||
import org.apache.poi.ss.formula.eval.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.formula.eval.EvaluationException;
|
||||
import org.apache.poi.ss.formula.eval.NumberEval;
|
||||
import org.apache.poi.ss.formula.eval.OperandResolver;
|
||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||
|
||||
/**
|
||||
* Implementation for Excel DELTA() function.<p>
|
||||
|
@ -46,33 +48,20 @@ public final class Delta extends Fixed2ArgFunction implements FreeRefFunction {
|
|||
private final static NumberEval ZERO = new NumberEval(0);
|
||||
|
||||
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2) {
|
||||
ValueEval veText1;
|
||||
try {
|
||||
veText1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
|
||||
Double number1 = evaluateValue(arg1, srcRowIndex, srcColumnIndex);
|
||||
if (number1 == null) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
Double number2 = evaluateValue(arg2, srcRowIndex, srcColumnIndex);
|
||||
if (number2 == null) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
return (number1.compareTo(number2) == 0) ? ONE : ZERO;
|
||||
} catch (EvaluationException e) {
|
||||
return e.getErrorEval();
|
||||
}
|
||||
String strText1 = OperandResolver.coerceValueToString(veText1);
|
||||
Double number1 = OperandResolver.parseDouble(strText1);
|
||||
if (number1 == null) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
ValueEval veText2;
|
||||
try {
|
||||
veText2 = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex);
|
||||
} catch (EvaluationException e) {
|
||||
return e.getErrorEval();
|
||||
}
|
||||
|
||||
String strText2 = OperandResolver.coerceValueToString(veText2);
|
||||
Double number2 = OperandResolver.parseDouble(strText2);
|
||||
if (number2 == null) {
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
int result = new BigDecimal(number1.doubleValue()).compareTo(new BigDecimal(number2.doubleValue()));
|
||||
return result == 0 ? ONE : ZERO;
|
||||
}
|
||||
|
||||
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
|
||||
|
@ -82,4 +71,10 @@ public final class Delta extends Fixed2ArgFunction implements FreeRefFunction {
|
|||
|
||||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
private static Double evaluateValue(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
|
||||
ValueEval veText = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
|
||||
String strText1 = OperandResolver.coerceValueToString(veText);
|
||||
return OperandResolver.parseDouble(strText1);
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ public final class Fixed implements Function1Arg, Function2Arg, Function3Arg {
|
|||
return ErrorEval.VALUE_INVALID;
|
||||
}
|
||||
|
||||
@SuppressWarnings("squid:S2111")
|
||||
private ValueEval fixed(
|
||||
ValueEval numberParam, ValueEval placesParam,
|
||||
ValueEval skipThousandsSeparatorParam,
|
||||
|
@ -93,8 +94,8 @@ public final class Fixed implements Function1Arg, Function2Arg, Function3Arg {
|
|||
NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
|
||||
DecimalFormat formatter = (DecimalFormat)nf;
|
||||
formatter.setGroupingUsed(!(skipThousandsSeparator != null && skipThousandsSeparator));
|
||||
formatter.setMinimumFractionDigits(places >= 0 ? places : 0);
|
||||
formatter.setMaximumFractionDigits(places >= 0 ? places : 0);
|
||||
formatter.setMinimumFractionDigits(Math.max(places, 0));
|
||||
formatter.setMaximumFractionDigits(Math.max(places, 0));
|
||||
String numberString = formatter.format(number.doubleValue());
|
||||
|
||||
// Return the result as a StringEval.
|
||||
|
|
|
@ -31,6 +31,8 @@ import org.apache.poi.ss.formula.eval.ValueEval;
|
|||
* @see <a href="http://office.microsoft.com/en-us/excel-help/irr-HP005209146.aspx">Excel IRR</a>
|
||||
*/
|
||||
public final class Irr implements Function {
|
||||
private static final int MAX_ITERATION_COUNT = 20;
|
||||
private static final double ABSOLUTE_ACCURACY = 1E-7;
|
||||
|
||||
|
||||
public ValueEval evaluate(final ValueEval[] args, final int srcRowIndex, final int srcColumnIndex) {
|
||||
|
@ -89,27 +91,24 @@ public final class Irr implements Function {
|
|||
* http://en.wikipedia.org/wiki/Newton%27s_method</a>
|
||||
*/
|
||||
public static double irr(double[] values, double guess) {
|
||||
final int maxIterationCount = 20;
|
||||
final double absoluteAccuracy = 1E-7;
|
||||
|
||||
double x0 = guess;
|
||||
double x1;
|
||||
|
||||
int i = 0;
|
||||
while (i < maxIterationCount) {
|
||||
for (int i = 0; i < MAX_ITERATION_COUNT; i++) {
|
||||
|
||||
// the value of the function (NPV) and its derivate can be calculated in the same loop
|
||||
final double factor = 1.0 + x0;
|
||||
int k = 0;
|
||||
double fValue = values[k];
|
||||
double denominator = factor;
|
||||
if (denominator == 0) {
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
double fValue = values[0];
|
||||
double fDerivative = 0;
|
||||
for (double denominator = factor; ++k < values.length; ) {
|
||||
for (int k = 1; k < values.length; k++) {
|
||||
final double value = values[k];
|
||||
fValue += value / denominator;
|
||||
denominator *= factor;
|
||||
if (denominator == 0) {
|
||||
return Double.NaN;
|
||||
}
|
||||
fDerivative -= k * value / denominator;
|
||||
}
|
||||
|
||||
|
@ -117,14 +116,13 @@ public final class Irr implements Function {
|
|||
if (fDerivative == 0) {
|
||||
return Double.NaN;
|
||||
}
|
||||
x1 = x0 - fValue/fDerivative;
|
||||
double x1 = x0 - fValue/fDerivative;
|
||||
|
||||
if (Math.abs(x1 - x0) <= absoluteAccuracy) {
|
||||
if (Math.abs(x1 - x0) <= ABSOLUTE_ACCURACY) {
|
||||
return x1;
|
||||
}
|
||||
|
||||
x0 = x1;
|
||||
++i;
|
||||
}
|
||||
// maximum number of iterations is exceeded
|
||||
return Double.NaN;
|
||||
|
|
|
@ -281,7 +281,7 @@ public class DataFormatter implements Observer {
|
|||
|
||||
/**
|
||||
* Return a Format for the given cell if one exists, otherwise try to
|
||||
* create one. This method will return <code>null</code> if the any of the
|
||||
* create one. This method will return <code>null</code> if any of the
|
||||
* following is true:
|
||||
* <ul>
|
||||
* <li>the cell's style is null</li>
|
||||
|
@ -826,6 +826,16 @@ public class DataFormatter implements Observer {
|
|||
return null;
|
||||
}
|
||||
Format dateFormat = getFormat(cell, cfEvaluator);
|
||||
if (dateFormat == null) {
|
||||
if (defaultDateformat == null) {
|
||||
DateFormatSymbols sym = DateFormatSymbols.getInstance(LocaleUtil.getUserLocale());
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", sym);
|
||||
sdf.setTimeZone(LocaleUtil.getUserTimeZone());
|
||||
dateFormat = sdf;
|
||||
} else {
|
||||
dateFormat = defaultNumFormat;
|
||||
}
|
||||
}
|
||||
synchronized (dateFormat) {
|
||||
if(dateFormat instanceof ExcelStyleDateFormatter) {
|
||||
// Hint about the raw excel value
|
||||
|
|
|
@ -55,6 +55,7 @@ public class ExcelGeneralNumberFormat extends Format {
|
|||
DataFormatter.setExcelStyleRoundingMode(decimalFormat);
|
||||
}
|
||||
|
||||
@SuppressWarnings("squid:S2111")
|
||||
public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
|
||||
final double value;
|
||||
if (number instanceof Number) {
|
||||
|
|
|
@ -104,6 +104,7 @@ public class FractionFormat extends Format {
|
|||
maxDenom = tmpMax;
|
||||
}
|
||||
|
||||
@SuppressWarnings("squid:S2111")
|
||||
public String format(Number num) {
|
||||
|
||||
final BigDecimal doubleValue = new BigDecimal(num.doubleValue());
|
||||
|
|
|
@ -820,7 +820,7 @@ public class HemfPlusDraw {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("squid:S2111")
|
||||
static double round10(double d) {
|
||||
return new BigDecimal(d).setScale(10, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue