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 オブジェクト毎に1つ作成されます。 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 = "8.5.5.1 (2024/02/29)"; 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 * @og.rev 8.5.5.1 (2024/02/29) switch式の使用 092 * 093 * @param clm DBColumnオブジェクト 094 * 095 * @return CellRendererオブジェクト 096 * @og.rtnNotNull 097 */ 098 public CellRenderer newInstance( final DBColumn clm ) { 099 // 単位は、RendererParamから取得 100 final String tani = StringUtil.nval( clm.getRendererParam() , "" ); 101 102 long div = 1L; 103 104 // KB,MB,GB,TB は、それぞれを、1024の倍数で割り算して求めます。 105 // それ以外では、K*,M*,G* に対して、先頭文字で判断して、1000の倍数で割り算します。 106 if( !tani.isEmpty() ) { 107 final char ch1 = tani.charAt(0); // 最初の文字(K,M,G,T) 108 final int base = tani.length() >= 2 && tani.charAt(1) == 'B' ? 1024 : 1000 ; 109 110 // 8.5.5.1 (2024/02/29) switch式の使用 111// switch( ch1 ) { 112// case 'K' : div = base; break; 113// case 'M' : div = base*base; break; 114// case 'G' : div = base*base*base; break; 115// case 'T' : div = base*base*base*base; break; 116// default : div = 1L; break; 117// } 118 div = switch( ch1 ) { 119 case 'K' -> div = base; 120 case 'M' -> div = base*base; 121 case 'G' -> div = base*base*base; 122 case 'T' -> div = base*base*base*base; 123 default -> div = 1L; 124 }; 125 } 126 127 return new Renderer_UNIT( tani,div ); 128 } 129 130 /** 131 * データの表示用文字列を返します。 132 * 133 * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加 134 * 135 * @param value 入力値(『数字型文字列』) 136 * 137 * @return データの表示用文字列 138 * @og.rtnNotNull 139 */ 140 @Override 141 public String getValue( final String value ) { 142 return getValue( value , true ); 143 } 144 145 /** 146 * データ出力用の文字列を作成します。 147 * ファイル等に出力する形式を想定しますので、HTMLタグを含まない 148 * 生データを返します。 149 * 基本は、#getValue( String ) をそのまま返します。 150 * 151 * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加 152 * 153 * @param value 入力値(『数字型文字列』) 154 * 155 * @return データ出力用の文字列(数字型文字列 のみ) 156 * @og.rtnNotNull 157 * @see #getValue( String ) 158 */ 159 @Override 160 public String getWriteValue( final String value ) { 161 return getValue( value , false ); 162 } 163 164 /** 165 * データ表示用/出力用の文字列を作成します。 166 * 第二引数の isView == true で、データ表示用文字列を、false で 167 * データ出力用の文字列を作成します。 168 * 処理の共通化を行うためのメソッドです。 169 * 170 * @og.rev 7.2.3.1 (2020/04/17) Renderer_UNIT 新規追加 171 * 172 * @param value 入力値(『数字型文字列』) 173 * @param isView データ表示用かどうか(true:表示用/false:出力用) 174 * 175 * @return データ表示用/出力用の文字列 176 * @og.rtnNotNull 177 * @see #getValue( String ) 178 */ 179 private String getValue( final String value , final boolean isView ) { 180 // 8.5.4.2 (2024/01/12) PMD 7.0.0 InefficientEmptyStringCheck 対応 181// String rtn = value == null || value.trim().isEmpty() ? "0" : value ; 182 String rtn = StringUtil.isNull( value ) ? "0" : value ; 183 184 final long val = ( Long.parseLong( rtn ) + division - 1 ) / division ; // 切り上げ 185 186 synchronized( FMT1 ) { // 7.2.9.5 (2020/11/28) 187 rtn = FMT1.format( val ) + " " + unit ; 188 } 189 190 // 8.5.5.1 (2024/02/29) PMD 7.0.0 OnlyOneReturn メソッドには終了ポイントが 1 つだけ必要 191// if( !isView ) { return rtn; } // 6.2.0.0 (2015/02/27) マイナス記号のまま 192 193// if( StringUtil.startsChar( rtn , '-' ) ) { 194 if( isView && StringUtil.startsChar( rtn , '-' ) ) { 195 rtn = "<span class=\"minus\">" + rtn + "</span>"; 196 } 197 return rtn; 198 } 199}