    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.plugin.column;
    017
    018import java.text.DecimalFormat;
    019
    020import org.opengion.fukurou.util.StringUtil;
    021import org.opengion.hayabusa.db.AbstractRenderer;
    022import org.opengion.hayabusa.db.CellRenderer;
    023import org.opengion.hayabusa.db.DBColumn;
    024
    025/**
    026 * UNIT レンデラーは、カラムのデータの単位変換を行う場合に使用するクラスです。
    027 *
    028 * マイナス表示はありません。
    029 * 単位は、RendererParam で指定します。
    030 * 単位の自動変換を（ある程度）サポートします。
    031 * KB,MB,GB,TB は、それぞれを、1024の倍数で割り算して求めます。
    032 * それ以外では、K*,M*,G* に対して、先頭文字で判断して、1000の倍数で割り算します。
    033 * それ以外の単位変換は、サポートしていません。
    034 * (数値の後ろに変換なしで文字列を付けるだけです。)
    035 *
    036 * 負数の場合はspanタグclass="minus"を付けて出力します。
    037 *
    038 * 単位変換時の小数点は切り上げします。ただし、データが nullかゼロ文字列か、0 の場合は、0 になります。
    039 * 1Byteのﾌｧｲﾙの場合は、1 KB という表示になります。
    040 *
    041 * カラムの表示に必要な属性は, DBColumn オブジェクト より取り出します。
    042 * このクラスは、DBColumn オブジェクト毎に１つ作成されます。
    043 *
    044 * @og.group データ表示
    045 * @og.rev 7.2.3.1 (2020/04/17) 新規追加
    046 *
    047 * @version  7.2
    048 * @author       Kazuhiko Hasegawa
    049 * @since    JDK11.0,
    050 */
    051public class Renderer_UNIT extends AbstractRenderer {
    052        /** このプログラムのVERSION文字列を設定します。   {@value} */
    053        private static final String VERSION = "7.2.3.1 (2020/04/17)" ;
    054
    055        private static final DecimalFormat FMT1 = new DecimalFormat( "#,##0" );
    056
    057        private final String    unit ;
    058        private final long              division ;
    059
    060        /**
    061         * デフォルトコンストラクター。
    062         * このコンストラクターで、基本オブジェクトを作成します。
    063         *
    064         * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加
    065         *
    066         */
    067        public Renderer_UNIT() {
    068                this( "",1L );
    069        }
    070
    071        /**
    072         * コンストラクター
    073         *
    074         * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加
    075         *
    076         * @param       tani    単位記号
    077         * @param       div             単位換算の除数
    078         */
    079        private Renderer_UNIT( final String tani,final long div ) {
    080                super();
    081                unit             = tani;
    082                division         = div;
    083        }
    084
    085        /**
    086         * 各オブジェクトから自分のインスタンスを返します。
    087         * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に
    088         * まかされます。
    089         *
    090         * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加
    091         *
    092         * @param       clm     DBColumnオブジェクト
    093         *
    094         * @return      CellRendererオブジェクト
    095         * @og.rtnNotNull
    096         */
    097        public CellRenderer newInstance( final DBColumn clm ) {
    098                // 単位は、RendererParamから取得
    099                final String tani = StringUtil.nval( clm.getRendererParam() , "" );
    100
    101                long div = 1L;
    102
    103                // KB,MB,GB,TB は、それぞれを、1024の倍数で割り算して求めます。
    104                // それ以外では、K*,M*,G* に対して、先頭文字で判断して、1000の倍数で割り算します。
    105                if( !tani.isEmpty() ) {
    106                        final char ch1 = tani.charAt(0);                // 最初の文字(K,M,G,T)
    107                        final int base = tani.length() >= 2 && tani.charAt(1) == 'B' ? 1024 : 1000 ;
    108
    109                        switch( ch1 ) {
    110                                case 'K' : div = base; break;
    111                                case 'M' : div = base*base; break;
    112                                case 'G' : div = base*base*base; break;
    113                                case 'T' : div = base*base*base*base; break;
    114                                default  : div = 1L; break;
    115                        }
    116                }
    117
    118                return new Renderer_UNIT( tani,div );
    119        }
    120
    121        /**
    122         * データの表示用文字列を返します。
    123         *
    124         * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加
    125         *
    126         * @param       value 入力値(『数字型文字列』)
    127         *
    128         * @return      データの表示用文字列
    129         * @og.rtnNotNull
    130         */
    131        @Override
    132        public String getValue( final String value ) {
    133                return getValue( value , true );
    134        }
    135
    136        /**
    137         * データ出力用の文字列を作成します。
    138         * ファイル等に出力する形式を想定しますので、HTMLタグを含まない
    139         * 生データを返します。
    140         * 基本は、#getValue( String ) をそのまま返します。
    141         *
    142         * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加
    143         *
    144         * @param       value 入力値(『数字型文字列』)
    145         *
    146         * @return  データ出力用の文字列(数字型文字列 のみ)
    147         * @og.rtnNotNull
    148         * @see         #getValue( String )
    149         */
    150        @Override
    151        public String getWriteValue( final String value ) {
    152                return getValue( value , false );
    153        }
    154
    155        /**
    156         * データ表示用/出力用の文字列を作成します。
    157         * 第二引数の isView == true で、データ表示用文字列を、false で
    158         * データ出力用の文字列を作成します。
    159         * 処理の共通化を行うためのメソッドです。
    160         *
    161         * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加
    162         *
    163         * @param       value 入力値(『数字型文字列』)
    164         * @param   isView データ表示用かどうか(true:表示用/false:出力用)
    165         *
    166         * @return  データ表示用/出力用の文字列
    167         * @og.rtnNotNull
    168         * @see         #getValue( String )
    169         */
    170        private String getValue( final String value , final boolean isView ) {
    171                String rtn = value == null || value.trim().isEmpty() ? "0" : value ;
    172
    173                final long val = ( Long.parseLong( rtn ) + division - 1 ) / division ;          // 切り上げ
    174
    175                synchronized( FMT1 ) {                                                  // 7.2.9.5 (2020/11/28)
    176                        rtn = FMT1.format( val ) + " " + unit ;
    177                }
    178
    179                if( !isView ) { return rtn; }                                   // 6.2.0.0 (2015/02/27) マイナス記号のまま
    180
    181                if( StringUtil.startsChar( rtn , '-' ) ) {
    182                        rtn = "<span class=\"minus\">" + rtn + "</span>";
    183                }
    184                return rtn;
    185        }
    186}