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