Uploaded image for project: 'Teeda'
  1. Teeda
  2. TEEDA-377

@NumberLengthにてDecimal型のチェックが行われない

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.0.11
    • Component/s: Teeda Extension
    • Labels:
      None
    • Environment:
      Windows Vista / jdk1.6.0_02

      Description

      Decimal型のフィールド(小数点あり)に対しNumberLengthValidatorにてチェックを行おうとしたところ、チェックが行われない。
      TnumberLengthValidator の getDigits メソッドにて、パラメタvalue のタイプがDecimalの場合の対応を行っていないのが原因と思われる。

        Activity

        Hide
        shot shot added a comment -

        TNumberLengthValidator.getDigits()で下記のように対応しています.
        もう少し具体例をお願いします.

            protected Digits getDigits(final FacesContext context, final Object value) {
                final Digits digits = new Digits();
                if (value instanceof Integer) {
                    final Integer num = (Integer) value;
                    final int abs = Math.abs(num.intValue());
                    digits.setIntegral(String.valueOf(abs).length());
                } else if (value instanceof Long) {
                    final Long num = (Long) value;
                    final long abs = Math.abs(num.longValue());
                    digits.setIntegral(String.valueOf(abs).length());
                } else if (value instanceof BigDecimal) {
                    BigDecimal num = (BigDecimal) value;
                    if (num.compareTo(ZERO) < 0) {
                        num = num.negate();
                    }
                    final String s = num.toString();
                    final Locale locale = context.getViewRoot().getLocale();
                    final String decimalSeparator = NumberConversionUtil
                            .findDecimalSeparator(locale);
                    final int pos = s.indexOf(decimalSeparator);
                    if (-1 < pos) {
                        digits.setIntegral(s.substring(0, pos).length());
                        digits.setFraction(s.substring(pos + 1).length());
                    } else {
                        digits.setIntegral(s.length());
                    }
                }
                return digits;
            }
        
        
        Show
        shot shot added a comment - TNumberLengthValidator.getDigits()で下記のように対応しています. もう少し具体例をお願いします. protected Digits getDigits( final FacesContext context, final Object value) { final Digits digits = new Digits(); if (value instanceof Integer ) { final Integer num = ( Integer ) value; final int abs = Math .abs(num.intValue()); digits.setIntegral( String .valueOf(abs).length()); } else if (value instanceof Long ) { final Long num = ( Long ) value; final long abs = Math .abs(num.longValue()); digits.setIntegral( String .valueOf(abs).length()); } else if (value instanceof BigDecimal) { BigDecimal num = (BigDecimal) value; if (num.compareTo(ZERO) < 0) { num = num.negate(); } final String s = num.toString(); final Locale locale = context.getViewRoot().getLocale(); final String decimalSeparator = NumberConversionUtil .findDecimalSeparator(locale); final int pos = s.indexOf(decimalSeparator); if (-1 < pos) { digits.setIntegral(s.substring(0, pos).length()); digits.setFraction(s.substring(pos + 1).length()); } else { digits.setIntegral(s.length()); } } return digits; }
        Hide
        Anonymous added a comment -

        value が Decimal型(BigDecimalではない) の場合、getDigitsメソッドにて判定をしていない( value instanceof Decimalの条件文がない)ため、digitsのintegral, fractionの値がゼロのままリターンしてしまう。結果、TNumberLengthValidator.validateメソッドでチェックエラーとならない。

        Show
        Anonymous added a comment - value が Decimal型(BigDecimalではない) の場合、getDigitsメソッドにて判定をしていない( value instanceof Decimalの条件文がない)ため、digitsのintegral, fractionの値がゼロのままリターンしてしまう。結果、TNumberLengthValidator.validateメソッドでチェックエラーとならない。
        Hide
        koichik koichik added a comment -

        BigDecimal ではない Decimal とは? FQN で書いてください.
        BigInteger は整数 (小数点以下がない) なので該当しませんよね.

        Show
        koichik koichik added a comment - BigDecimal ではない Decimal とは? FQN で書いてください. BigInteger は整数 (小数点以下がない) なので該当しませんよね.
        Hide
        yanashin Shinichi Yanagisawa added a comment -

        すみません。Double型の間違いでした。
        今までのコメントについて、Decimal型をDouble型に読み替えてください。

        Show
        yanashin Shinichi Yanagisawa added a comment - すみません。Double型の間違いでした。 今までのコメントについて、Decimal型をDouble型に読み替えてください。
        Hide
        koichik koichik added a comment -

        Double に NumberLengthValidator?
        そういうことがしたいなら Double ではなく BigDecimal を使うべきだと思いますが.

        そもそも Double (double) の長さとは?
        例えば 1.23E45 はどのようにバリデーションすべきでしょうか?
        仮数部・指数部ではなく,整数部・小数部の長さでバリデートするのでしょうか?
        あるいは,0.1 のように正確に表現できない値の場合はどうすべきでしょうか? 適当に丸めるべきですか?
        それらの仕様は Teeda としてサポートする必要があるほど一般的でしょうか?

        それよりは,以下のようにした方がいいのでは?

        public class HogePage {
          @NumberLength(...)
          public BigDecimal foo;
        
          public Double getFooAsDouble() {
            return foo == null ? null ? foo.doubleValue();
          }
        }
        
        Show
        koichik koichik added a comment - Double に NumberLengthValidator? そういうことがしたいなら Double ではなく BigDecimal を使うべきだと思いますが. そもそも Double (double) の長さとは? 例えば 1.23E45 はどのようにバリデーションすべきでしょうか? 仮数部・指数部ではなく,整数部・小数部の長さでバリデートするのでしょうか? あるいは,0.1 のように正確に表現できない値の場合はどうすべきでしょうか? 適当に丸めるべきですか? それらの仕様は Teeda としてサポートする必要があるほど一般的でしょうか? それよりは,以下のようにした方がいいのでは? public class HogePage { @NumberLength(...) public BigDecimal foo; public Double getFooAsDouble() { return foo == null ? null ? foo.doubleValue(); } }
        Hide
        yanashin Shinichi Yanagisawa added a comment -

        実は意図してDoubleを使った訳ではありません。
        私はTeedaの初心者ですが、Teedaを理解するためにteeda-html-exampleを試していたのですが、
        その中の「6.足し算による入力サンプル(金額入力系コンポーネント)」(AddExtPage.java)では、下記のようにコーディングされていました。
        @NumberConverter(pattern = "#.0000", type = "currency")
        @NumberLength(integralMax = 12, fractionMax = 2)
        @GreaterThanConstant
        private BigDecimal arg1;
        arg1に小数点3桁以上の数値(例えば(「1000.111」)を入力すれば当然エラーになると思ったところなぜかエラーになりませんでした。なぜだろうとコードを追って行ったところ、@NumberConverterはDoubleで返却されるようになっており、@NumberLengthでは上述したようにDoubleをサポートしていないためチェックが行われていないということが判り、今回コメントを記述しました。
        おっしゃる通りDouble型では少数部の表現が正確ではないため@NunberLengthで少数部をチェックするのは不適当ですね。ただTeedaを利用するものとしては正しく記述しているつもりでもそれが内部で無視されてしまい、原因不明の状態に陥るのはいただけないですね。なんらかの方法でそれは誤った使い方だと利用者に判るようにして欲しいです。

        Show
        yanashin Shinichi Yanagisawa added a comment - 実は意図してDoubleを使った訳ではありません。 私はTeedaの初心者ですが、Teedaを理解するためにteeda-html-exampleを試していたのですが、 その中の「6.足し算による入力サンプル(金額入力系コンポーネント)」(AddExtPage.java)では、下記のようにコーディングされていました。 @NumberConverter(pattern = "#.0000", type = "currency") @NumberLength(integralMax = 12, fractionMax = 2) @GreaterThanConstant private BigDecimal arg1; arg1に小数点3桁以上の数値(例えば(「1000.111」)を入力すれば当然エラーになると思ったところなぜかエラーになりませんでした。なぜだろうとコードを追って行ったところ、@NumberConverterはDoubleで返却されるようになっており、@NumberLengthでは上述したようにDoubleをサポートしていないためチェックが行われていないということが判り、今回コメントを記述しました。 おっしゃる通りDouble型では少数部の表現が正確ではないため@NunberLengthで少数部をチェックするのは不適当ですね。ただTeedaを利用するものとしては正しく記述しているつもりでもそれが内部で無視されてしまい、原因不明の状態に陥るのはいただけないですね。なんらかの方法でそれは誤った使い方だと利用者に判るようにして欲しいです。
        Hide
        shot shot added a comment -

        NumberConverterというか、DecimalFormatSymbols/DecimalFormatを使ったとしても
        JDK1.4ではNumberFormatがDoubleかLongしか返せないのです.

        というわけで、サンプルが適切でないのは修正しておきます.
        代わりに@BigDecimalを使ってください.

        TNumberLengthValidatorでDoubleが指定されているときは例外飛ばすようにしておきます.
        >正しく記述しているつもりでもそれが内部で無視されてしまい、原因不明の状態に陥るのはいただけない

        Show
        shot shot added a comment - NumberConverterというか、DecimalFormatSymbols/DecimalFormatを使ったとしても JDK1.4ではNumberFormatがDoubleかLongしか返せないのです. というわけで、サンプルが適切でないのは修正しておきます. 代わりに@BigDecimalを使ってください. TNumberLengthValidatorでDoubleが指定されているときは例外飛ばすようにしておきます. >正しく記述しているつもりでもそれが内部で無視されてしまい、原因不明の状態に陥るのはいただけない
        Hide
        shot shot added a comment -

        Rev.3594にて修正しました.

        Double型のプロパティでTNumberLengthValidatorを指定している場合、
        明示的に例外をとばすようにしました.
        (TNumberLengthValidatorがInteger、Long、BigDecimalしか扱えないため)

        Show
        shot shot added a comment - Rev.3594にて修正しました. Double型のプロパティでTNumberLengthValidatorを指定している場合、 明示的に例外をとばすようにしました. (TNumberLengthValidatorがInteger、Long、BigDecimalしか扱えないため)
        Hide
        koichik koichik added a comment -

        To: Yanagisawa さん

        TEEDA-378 も同様ですが,そういう場合は問題となっている状況自体を書いていただいた方がいいです.
        今回の場合は,「teeda-html-example の add/addExt.html で小数点以下に 3 桁以上入力してもエラーにならない」などであれば,より円滑に状況が伝わったと思います.
        問題と同時に原因や解決策を書き添えていただくのは構わないのですが,原因 (の推測) と解決策 (の案) だけでは問題を理解することができません.
        またご報告いただける際にはその点を考慮してください.よろしくお願いします.

        Show
        koichik koichik added a comment - To: Yanagisawa さん TEEDA-378 も同様ですが,そういう場合は問題となっている状況自体を書いていただいた方がいいです. 今回の場合は,「teeda-html-example の add/addExt.html で小数点以下に 3 桁以上入力してもエラーにならない」などであれば,より円滑に状況が伝わったと思います. 問題と同時に原因や解決策を書き添えていただくのは構わないのですが,原因 (の推測) と解決策 (の案) だけでは問題を理解することができません. またご報告いただける際にはその点を考慮してください.よろしくお願いします.

          People

          • Assignee:
            shot shot
            Reporter:
            yanashin Shinichi Yanagisawa
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development