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 org.opengion.fukurou.util.StringUtil; 019import org.opengion.hayabusa.db.AbstractRenderer; 020import org.opengion.hayabusa.db.CellRenderer; 021import org.opengion.hayabusa.db.DBColumn; 022 023/** 024 * MONEY レンデラーは、カラムのデータを金額表示する場合に使用するクラスです。 025 * 026 * マイナス時の表示は、id="minus" をキーに CSSファイルで指定しています。 027 * 通貨は、標準では、¥ですが、値:記号 という形式で指定すれば、各値ごとに 028 * 通貨を指定できます。(ただし、通貨変換は、サポートしていません。) 029 * 負数の場合はspanタグclass="minus"を付けて出力します。 030 * 031 * カラムの表示に必要な属性は、DBColumn オブジェクト より取り出します。 032 * このクラスは、DBColumn オブジェクト毎に1つ作成されます。 033 * 034 * 6.8.3.1 (2017/12/01) 035 * 小数点で桁ぞろえするため、小数点以下、4桁のスペースと、pre 属性、右寄せを標準に入れます。 036 * 037 * 6.9.7.0 (2018/05/14) 038 * RendererParam で、記号(¥など)を指定できるようにします。 039 * 040 * @og.group データ表示 041 * @og.rev 5.4.3.6 (2012/01/19) コメント修正 042 * 043 * @version 4.0 044 * @author Kazuhiko Hasegawa 045 * @since JDK5.0, 046 */ 047public class Renderer_MONEY extends AbstractRenderer { 048 /** このプログラムのVERSION文字列を設定します。 {@value} */ 049 private static final String VERSION = "6.9.7.0 (2018/05/14)" ; 050 051 private static final String DEF_KIGO = "¥" ; // 6.9.7.0 (2018/05/14) 052 private static final String MINUS_MRK = "▲" ; // 6.9.7.0 (2018/05/14) 053 054 private static final String[] SPACE = { // 6.8.3.1 (2017/12/01) 追加 055 " ", // size == 0 056 " ", // size == 1 057 " ", // size == 2 058 " ", // size == 3 059 "" // size == 4 060 }; 061 062 private static final CellRenderer[] DB_CELL = { 063 new Renderer_MONEY(), 064 new Renderer_MONEY("",1,null,DEF_KIGO), 065 new Renderer_MONEY("",2,null,DEF_KIGO), 066 new Renderer_MONEY("",3,null,DEF_KIGO), // 6.8.3.1 (2017/12/01) 追加 067 new Renderer_MONEY("",4,null,DEF_KIGO) // 6.8.3.1 (2017/12/01) 追加 068 }; 069 070 private final String defValue ; // 6.8.3.1 (2017/12/01) 追加 071 private final int minFraction; 072 private final String noDisplayVal ; // 5.6.2.3 (2013/03/22) 073 private final String kigo ; // 6.9.7.0 (2018/05/14) 074 075 /** 076 * デフォルトコンストラクター。 077 * このコンストラクターで、基本オブジェクトを作成します。 078 * 079 * @og.rev 3.1.1.1 (2003/04/03) 各オブジェクトから自分のインスタンスを返すファクトリメソッドを追加。 080 * @og.rev 3.3.0.0 (2003/06/23) 初期値設定追加。 081 * @og.rev 5.6.2.3 (2013/03/22) noDisplayVal 変数初期化 082 * @og.rev 6.9.7.0 (2018/05/14) 記号追加 083 * 084 */ 085 public Renderer_MONEY() { 086// this( "",0,null ); // 6.0.2.4 (2014/10/17) 087 this( "",0,null,DEF_KIGO ); // 6.9.7.0 (2018/05/14) 記号追加 088 } 089 090 /** 091 * コンストラクター 092 * 093 * @og.rev 6.0.2.4 (2014/10/17) noDisplayVal 対応漏れのため、追加 094 * @og.rev 6.9.7.0 (2018/05/14) 記号追加 095 * 096 * @param defval 初期値 097 * @param size 小数点 098 * @param noDispVal 非表示文字の設定 099 * @param mkigo マネー記号 100 */ 101// private Renderer_MONEY( final String defval , final int size , final String noDispVal ) { 102 private Renderer_MONEY( final String defval , final int size , final String noDispVal , final String mkigo ) { 103 super(); // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 104 defValue = defval; 105 minFraction = size ; 106 noDisplayVal = noDispVal; // 5.5.1.0 (2012/04/03) 107 kigo = mkigo; // 6.9.7.0 (2018/05/14) 108 } 109 110 /** 111 * 各オブジェクトから自分のインスタンスを返します。 112 * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に 113 * まかされます。 114 * 115 * @og.rev 3.1.1.1 (2003/04/03) 各オブジェクトから自分のインスタンスを返すファクトリメソッドを追加。 116 * @og.rev 3.1.2.1 (2003/04/10) synchronized を、削除します。 117 * @og.rev 6.0.4.0 (2014/11/28) 表示は、ViewLength属性を元に行う。 118 * @og.rev 6.8.3.1 (2017/12/01) size(minFraction)の最大値は、4(DB_CELL.length-1) とします。 119 * @og.rev 6.9.7.0 (2018/05/14) 記号追加 120 * 121 * @param clm DBColumnオブジェクト 122 * 123 * @return CellRendererオブジェクト 124 * @og.rtnNotNull 125 */ 126 public CellRenderer newInstance( final DBColumn clm ) { 127 final String defval = clm.getDefault(); 128 129 // 6.3.9.1 (2015/11/27) Found 'DD'-anomaly for variable(PMD) 130 131 // 6.0.4.0 (2014/11/28) 表示は、ViewLength属性があれば、それを使う。 132 final String viewLength = clm.getViewLength(); 133 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..; 134 int size ; 135 if( viewLength == null ) { 136 size = clm.getSizeY(); // 6.3.9.1 (2015/11/27) 137 } 138 else { 139 final int ch = viewLength.indexOf( ',' ) ; // DBColumn で、"." を "," に変換済み 140 size = ch > 0 ? Integer.parseInt( viewLength.substring( ch+1 ) ) : 0 ; 141 } 142 143 // 6.8.3.1 (2017/12/01) size(minFraction)の最大値は、4 とします。 144 if( size >= DB_CELL.length ) { size = DB_CELL.length - 1; } 145 146 final String noDispVal = clm.getNoDisplayVal(); // 6.0.2.4 (2014/10/17) 147 148 // 6.9.7.0 (2018/05/14) 記号追加 149 final String mkigo = StringUtil.nval( clm.getRendererParam() , DEF_KIGO ); 150 151 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method 152 return noDispVal == null && ( defval == null || defval.isEmpty() ) 153 ? DB_CELL[size] 154// : new Renderer_MONEY( defval,size,noDispVal ); 155 : new Renderer_MONEY( defval,size,noDispVal,mkigo ); // 6.9.7.0 (2018/05/14) 記号追加 156 } 157 158 /** 159 * データの表示用文字列を返します。 160 * 161 * 引数の値が、『数字型文字列:通貨』という値を渡すことで、通貨を 162 * 頭につけて通貨ごとに異なる値を表示させることができる。 163 * 164 * @og.rev 3.1.0.0 (2003/03/20) 内部に、DBColumn オブジェクトをキープしないように変更 165 * @og.rev 3.3.0.0 (2003/06/23) NumberFormatクラスは、廃止します。 166 * @og.rev 5.6.2.3 (2013/03/22) noDisplayVal 変数追加 167 * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化 168 * 169 * @param value 入力値(『数字型文字列』 または『数字型文字列:通貨』) 170 * 171 * @return データの表示用文字列 172 * @og.rtnNotNull 173 */ 174 @Override 175 public String getValue( final String value ) { 176 return getValue( value , true ); 177 } 178 179 /** 180 * データ出力用の文字列を作成します。 181 * ファイル等に出力する形式を想定しますので、HTMLタグを含まない 182 * データを返します。 183 * 基本は、#getValue( String ) をそのまま返します。 184 * 185 * @og.rev 6.0.4.0 (2014/11/28) データ出力用のレンデラー 186 * @og.rev 6.2.0.0 (2015/02/27) そのまま数値化できるように、数値部のみを返します。 187 * 188 * @param value 入力値(『数字型文字列』 または『数字型文字列:通貨』) 189 * 190 * @return データ出力用の文字列(数字型文字列 のみ) 191 * @og.rtnNotNull 192 * @see #getValue( String ) 193 */ 194 @Override 195 public String getWriteValue( final String value ) { 196 return getValue( value , false ); 197 } 198 199 /** 200 * データ表示用/出力用の文字列を作成します。 201 * 第二引数の isView == true で、データ表示用文字列を、false で 202 * データ出力用の文字列を作成します。 203 * 処理の共通化を行うためのメソッドです。 204 * 205 * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化 206 * @og.rev 6.2.0.0 (2015/02/27) マイナス金額を、"-" ではなく、"▲" にします。 207 * @og.rev 6.8.3.1 (2017/12/01) 小数点で桁ぞろえするため、小数点以下、4桁のスペースと、pre 属性、右寄せを標準に入れます。 208 * @og.rev 6.9.7.0 (2018/05/14) 記号追加 209 * 210 * @param value 入力値(『数字型文字列』 または『数字型文字列:通貨』) 211 * @param isView データ表示用かどうか(true:表示用/false:出力用) 212 * 213 * @return データ表示用/出力用の文字列 214 * @og.rtnNotNull 215 * @see #getValue( String ) 216 */ 217 private String getValue( final String value , final boolean isView ) { 218 // 5.6.2.3 (2013/03/22) noDisplayVal 変数追加 219 if( noDisplayVal != null && noDisplayVal.equalsIgnoreCase( value ) ) { return "" ; } 220 221 // 8.5.4.2 (2024/01/12) PMD 7.0.0 InefficientEmptyStringCheck 対応 222// String rtn = value == null || value.trim().isEmpty() ? defValue : value ; 223 String rtn = StringUtil.isNull( value ) ? defValue : value ; 224 if( rtn == null || rtn.isEmpty() ) { return "" ; } // 6.8.3.1 (2017/12/01) 225 226// String tuuka = "¥"; 227 String tuuka = kigo; // 6.9.7.0 (2018/05/14) 記号追加 228 final int taniPos = rtn.indexOf( ':' ); 229 if( taniPos >= 0 ) { 230 tuuka = rtn.substring( taniPos+1 ); // rtn に副作用があるため、先に処理 231 rtn = rtn.substring( 0,taniPos ); 232 } 233 234 boolean minus = false ; 235 if( StringUtil.startsChar( rtn , '-' ) ) { // 6.2.0.0 (2015/02/27) 1文字 String.startsWith 236 minus = true; 237 rtn = rtn.substring( 1 ); // マイナス記号は取っ払っておきます。 238 } 239 240 // 6.2.0.0 (2015/02/27) マイナス金額を、"-" ではなく、"▲" にします。 241// rtn = tuuka + (minus ? "▲" : "" ) + StringUtil.numberFormat( rtn,minFraction ) + "-"; 242 // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseStringBufferForStringAppends 対応 243// rtn = tuuka + (minus ? MINUS_MRK : "" ) + StringUtil.numberFormat( rtn,minFraction ) + "-"; // 6.9.7.0 (2018/05/14) "▲" → MINUS_MRK 244 final StringBuilder rtnBuf = new StringBuilder() 245 .append( tuuka ) 246 .append( minus ? MINUS_MRK : "" ) 247 .append( StringUtil.numberFormat( rtn,minFraction ) ) 248 .append( '-' ); 249 250 // 8.5.5.1 (2024/02/29) PMD 7.0.0 OnlyOneReturn メソッドには終了ポイントが 1 つだけ必要 251 // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseStringBufferForStringAppends 対応 252// if( !isView ) { return rtn; } // 6.2.0.0 (2015/02/27) マイナス記号のまま 253// if( !isView ) { return rtnBuf.toString(); } // 6.2.0.0 (2015/02/27) マイナス記号のまま 254 if( isView ) { 255 // 6.8.3.1 (2017/12/01) 小数点で桁ぞろえするため、小数点以下、4桁のスペースと、pre 属性、右寄せを標準に入れます。 256 // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseStringBufferForStringAppends 対応 257// rtn = "<pre>" + rtn + SPACE[minFraction] + "</pre>"; // preタグは、custom.css で、固定幅フォントを指定 258 rtnBuf.insert( 0,"<pre>" ) 259 .append( SPACE[minFraction] ) 260 .append( "</pre>" ); // preタグは、custom.css で、固定幅フォントを指定 261 262 if( minus ) { 263 // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseStringBufferForStringAppends 対応 264// rtn = "<span class=\"minus\">" + rtn + "</span>"; 265 rtnBuf.insert( 0,"<span class=\"minus\">" ) 266 .append( "</span>" ); 267 } 268 } 269// return rtn; 270 return rtnBuf.toString(); 271 } 272 273 /** 274 * name属性を変えた、データ表示用のHTML文字列を作成します。 275 * レンデラーのため、row(行番号)は使いません。 276 * 第3引数に、パラメータを渡すことが出来ます。これは、viewMarker で 277 * [$XXXX param] 形式を渡すことで、行単位に表示形式を変更できます。 278 * 279 * @og.rev 6.8.3.1 (2017/12/01) パラメータを渡せるようにします。 280 * @og.rev 6.9.7.0 (2018/05/14) 記号追加 281 * 282 * @param row 行番号 283 * @param value 値 284 * @param param パラメータ 285 * 286 * @return データ表示/編集用の文字列 287 */ 288 @Override 289 public String getValue( final int row,final String value,final String param ) { 290 int size = param == null || param.isEmpty() ? 0 : Integer.parseInt( param ); 291 if( size >= DB_CELL.length ) { size = DB_CELL.length - 1; } 292 293 final CellRenderer rende = noDisplayVal == null && ( defValue == null || defValue.isEmpty() ) 294 ? DB_CELL[size] 295// : new Renderer_MONEY( defValue,size,noDisplayVal,"¥" ); 296 : new Renderer_MONEY( defValue,size,noDisplayVal,DEF_KIGO ); // 6.9.7.0 (2018/05/14) 297 298 return rende.getValue( value ); 299 } 300}