Skip to content

Commit

Permalink
refs #24 数値型にマッピングする際にオーバーフローを起こしたときにエラーとするよう修正。
Browse files Browse the repository at this point in the history
  • Loading branch information
mygreen committed May 4, 2015
1 parent fe38747 commit 60b25b1
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@
*/
public abstract class AbstractCellConverter<T> implements CellConverter<T> {

/**
* 型変換失敗したときの例外{@link TypeBindException}をスローします。
* @since 0.5
* @param error
* @param cell
* @param adaptor
* @param targetValue
* @return
*/
public TypeBindException newTypeBindException(final Exception error,
final Cell cell, final FieldAdaptor adaptor, final Object targetValue) {

final String message = new StringBuilder()
.append(String.format("Fail conversion field value '%s' => type '%s'.",
Utils.convertToString(targetValue), adaptor.getTargetClass()))
.append(String.format(" Cell '%s' map to '%s#%s'.",
Utils.formatCellAddress(cell), adaptor.getDeclaringClass().getName(), adaptor.getName()))
.toString();

return new TypeBindException(error, message, adaptor.getTargetClass(), targetValue);

}

/**
* 型変換失敗したときの例外{@link TypeBindException}をスローします。
* @param cell
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ public class TypeBindException extends XlsMapperException {
/** validation時のメッセージの変数に使用する */
private final Map<String, Object> messageVars;

public TypeBindException(final Exception e, final String message, final Class<?> bindClass, final Object targetValue) {
super(message, e);
this.bindClass = bindClass;
this.targetValue = targetValue;
this.messageVars = new LinkedHashMap<String, Object>();
}

public TypeBindException(final String message, final Class<?> bindClass, final Object targetValue) {
super(message);
this.bindClass = bindClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.lang.annotation.Annotation;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
Expand Down Expand Up @@ -51,8 +52,9 @@ public T toObject(final Cell cell, final FieldAdaptor adaptor, final XlsMapperCo
resultValue = getZeroValue();
}

} else if(Utils.isNotEmpty(anno.pattern())) {
final String defaultValue = converterAnno.defaultValue();
} else {
String defaultValue = converterAnno.defaultValue();
defaultValue = Utils.trim(defaultValue, converterAnno);
try {
resultValue = parseNumber(defaultValue, createNumberFormat(anno));
} catch(ParseException e) {
Expand All @@ -63,15 +65,20 @@ public T toObject(final Cell cell, final FieldAdaptor adaptor, final XlsMapperCo

} else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
// セルのタイプが数値型の場合はそのまま取得する。
resultValue = convertNumber(cell.getNumericCellValue());
try {
resultValue = convertNumber(cell.getNumericCellValue());
} catch(ArithmeticException e) {
throw newTypeBindException(e, cell, adaptor, cell)
.addAllMessageVars(createTypeErrorMessageVars(anno));
}

} else {
String cellValue = POIUtils.getCellContents(cell, config.getCellFormatter());
cellValue = Utils.trim(cellValue, converterAnno);
if(Utils.isNotEmpty(cellValue)) {
try {
resultValue = parseNumber(cellValue, createNumberFormat(anno));
} catch(ParseException e) {
} catch(ParseException | ArithmeticException e) {
throw newTypeBindException(e, cell, adaptor, cellValue)
.addAllMessageVars(createTypeErrorMessageVars(anno));
}
Expand All @@ -95,21 +102,28 @@ public T toObject(final Cell cell, final FieldAdaptor adaptor, final XlsMapperCo
*/
protected NumberFormat createNumberFormat(final XlsNumberConverter anno) {

if(anno.pattern().isEmpty()) {
return null;
}

final Locale locale;
if(anno.locale().isEmpty()) {
locale = Locale.getDefault();
} else {
locale = Utils.getLocale(anno.locale());
}

final DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
if(anno.pattern().isEmpty()) {
if(anno.currency().isEmpty()) {
return null;
} else {
// 通貨の場合
return NumberFormat.getCurrencyInstance(locale);
}
}

final DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
final DecimalFormat format = new DecimalFormat(anno.pattern(), symbols);

format.setRoundingMode(RoundingMode.HALF_UP);
format.setParseBigDecimal(true);

if(Utils.isNotEmpty(anno.currency())) {
format.setCurrency(Currency.getInstance(anno.currency()));
}
Expand Down Expand Up @@ -196,7 +210,12 @@ protected T parseNumber(final String value, final NumberFormat format) throws Pa
throw new ParseException(String.format("'%s' cannot greater than %f", value, getMaxValue()), 0);
}

return convertNumber(result);
if(result instanceof BigDecimal) {
// NumberFormatのインスタンスを作成する際に、DecimalFormat#setParseBigDecimal(true)としているため、戻り値がBigDecimalになる。
return convertNumber((BigDecimal) result);
} else {
return convertNumber(result);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gh.mygreen.xlsmapper.cellconvert.converter;

import java.math.BigDecimal;
import java.math.RoundingMode;


/**
Expand All @@ -13,7 +14,10 @@ public class ByteCellConverter extends AbstractNumberCellConverter<Byte> {

@Override
protected Byte convertNumber(double value) {
return new BigDecimal(value).byteValue();
// 少数以下を四捨五入
BigDecimal decimal = new BigDecimal(value);
decimal = decimal.setScale(0, RoundingMode.HALF_UP);
return decimal.byteValueExact();
}

@Override
Expand All @@ -23,7 +27,9 @@ protected Byte convertNumber(final Number value) {

@Override
protected Byte convertNumber(final BigDecimal value) {
return value.byteValue();
// 少数以下を四捨五入
BigDecimal decimal = value.setScale(0, RoundingMode.HALF_UP);
return decimal.byteValueExact();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gh.mygreen.xlsmapper.cellconvert.converter;

import java.math.BigDecimal;
import java.math.RoundingMode;


/**
Expand All @@ -13,7 +14,10 @@ public class IntegerCellConverter extends AbstractNumberCellConverter<Integer> {

@Override
protected Integer convertNumber(double value) {
return new BigDecimal(value).intValue();
// 少数以下を四捨五入
BigDecimal decimal = new BigDecimal(value);
decimal = decimal.setScale(0, RoundingMode.HALF_UP);
return decimal.intValueExact();
}

@Override
Expand All @@ -23,7 +27,9 @@ protected Integer convertNumber(final Number value) {

@Override
protected Integer convertNumber(final BigDecimal value) {
return value.intValue();
// 少数以下を四捨五入
BigDecimal decimal = value.setScale(0, RoundingMode.HALF_UP);
return decimal.intValueExact();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gh.mygreen.xlsmapper.cellconvert.converter;

import java.math.BigDecimal;
import java.math.RoundingMode;


/**
Expand All @@ -13,7 +14,10 @@ public class LongCellConverter extends AbstractNumberCellConverter<Long> {

@Override
protected Long convertNumber(double value) {
return new BigDecimal(value).longValue();
// 少数以下を四捨五入
BigDecimal decimal = new BigDecimal(value);
decimal = decimal.setScale(0, RoundingMode.HALF_UP);
return decimal.longValueExact();
}

@Override
Expand All @@ -23,7 +27,9 @@ protected Long convertNumber(final Number value) {

@Override
protected Long convertNumber(final BigDecimal value) {
return value.longValue();
// 少数以下を四捨五入
BigDecimal decimal = value.setScale(0, RoundingMode.HALF_UP);
return decimal.longValueExact();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gh.mygreen.xlsmapper.cellconvert.converter;

import java.math.BigDecimal;
import java.math.RoundingMode;


/**
Expand All @@ -13,7 +14,10 @@ public class ShortCellConverter extends AbstractNumberCellConverter<Short> {

@Override
protected Short convertNumber(double value) {
return new BigDecimal(value).shortValue();
// 少数以下を四捨五入
BigDecimal decimal = new BigDecimal(value);
decimal = decimal.setScale(0, RoundingMode.HALF_UP);
return decimal.shortValueExact();
}

@Override
Expand All @@ -23,7 +27,9 @@ protected Short convertNumber(final Number value) {

@Override
protected Short convertNumber(final BigDecimal value) {
return value.shortValue();
// 少数以下を四捨五入
BigDecimal decimal = value.setScale(0, RoundingMode.HALF_UP);
return decimal.shortValueExact();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ public FieldErrorBuilder fieldValue(final Object fieldValue) {
return this;
}

public FieldErrorBuilder typeBindFailure(final boolean typeBindFailure) {
this.typeBindFailure = typeBindFailure;
return this;
}

public FieldErrorBuilder codes(String[] codes) {
this.codes = codes;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,7 @@ public void rejectTypeBind(final String field, final Object fieldValue, final Cl
addError(FieldErrorBuilder.create()
.objectName(getObjectName()).fieldPath(buildFieldPath(field))
.fieldValue(fieldValue).fieldType(fieldType)
.typeBindFailure(true)
.codes(getMessageCodeGenerator().generateTypeMismatchCodes(getObjectName(), field, fieldType), errorVars)
.build());
}
Expand All @@ -1000,6 +1001,7 @@ public void rejectSheetTypeBind(final String field, final Object fieldValue, fin
addError(FieldErrorBuilder.create()
.objectName(getObjectName()).fieldPath(buildFieldPath(field))
.fieldValue(fieldValue).fieldType(fieldType)
.typeBindFailure(true)
.codes(getMessageCodeGenerator().generateTypeMismatchCodes(getObjectName(), field, fieldType), errorVars)
.sheetName(getSheetName()).cellAddress(cellAddress)
.label(label)
Expand All @@ -1016,6 +1018,7 @@ public void rejectTypeBind(final String field, final Object fieldValue, final Cl
addError(FieldErrorBuilder.create()
.objectName(getObjectName()).fieldPath(buildFieldPath(field))
.fieldValue(fieldValue).fieldType(fieldType)
.typeBindFailure(true)
.codes(getMessageCodeGenerator().generateTypeMismatchCodes(getObjectName(), field, fieldType))
.build());
}
Expand All @@ -1030,9 +1033,10 @@ public void rejectTypeBind(final String field, final Object fieldValue, final Cl
*/
public void rejectSheetTypeBind(final String field, final Object fieldValue, final Class<?> fieldType,
final Point cellAddress, final String label) {
addError(FieldErrorBuilder.create()
addError(FieldErrorBuilder.create()
.objectName(getObjectName()).fieldPath(buildFieldPath(field))
.fieldValue(fieldValue).fieldType(fieldType)
.typeBindFailure(true)
.codes(getMessageCodeGenerator().generateTypeMismatchCodes(getObjectName(), field, fieldType))
.sheetName(getSheetName()).cellAddress(cellAddress)
.label(label)
Expand Down

0 comments on commit 60b25b1

Please sign in to comment.