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.hayabusa.db.AbstractRenderer; 019import org.opengion.hayabusa.db.CellRenderer; 020import org.opengion.hayabusa.db.DBColumn; 021import org.opengion.fukurou.util.StringUtil; 022 023import java.text.DecimalFormat; 024 025/** 026 * DECIMAL レンデラーは、カラムのデータをDecimal(10進数、小数)表示する場合に 027 * 使用するクラスです。 028 * 負数の場合はspanタグclass="minus"を付けて出力します。 029 * 030 * 表示パラメータに与えられた文字列は、java.text.DecimalFormat を 031 * 使用してフォーマットされます。 032 * フォーマット変換前に、カンマなどの数値変換時にエラーになる情報を削除しておきます。 033 * 034 * フォーマットルールは、{@link java.text.DecimalFormat} を参照願います。 035 * 標準のフォーマットは"#,##0.#"です。 036 * 037 * カラムの表示に必要な属性は、DBColumn オブジェクト より取り出します。 038 * このクラスは、DBColumn オブジェクト毎に1つ作成されます。 039 * 040 * @og.rev 3.5.0.0 (2003/09/17) 新規作成 041 * @og.rev 5.4.3.6 (2012/01/19) コメント修正 042 * @og.group データ表示 043 * 044 * @version 4.0 045 * @author Kazuhiko Hasegawa 046 * @since JDK5.0, 047 */ 048public class Renderer_DECIMAL extends AbstractRenderer { 049 /** このプログラムのVERSION文字列を設定します。 {@value} */ 050 private static final String VERSION = "6.8.3.1 (2017/12/01)" ; 051 052 private final DecimalFormat format ; 053 private final String defValue ; 054 private final String noDisplayVal ; // 5.6.2.3 (2013/03/22) 055 056 // 6.8.3.1 (2017/12/01) 標準オブジェクトのキャッシュ 057 private static final CellRenderer DB_CELL = new Renderer_DECIMAL(); 058 059 /** 060 * デフォルトコンストラクター。 061 * このコンストラクターで、基本オブジェクトを作成します。 062 * 063 * @og.rev 5.6.2.3 (2013/03/22) noDisplayVal 変数初期化 064 * @og.rev 6.8.3.1 (2017/12/01) 標準オブジェクトとして、利用できる形にして、キャッシュします。 065 */ 066 public Renderer_DECIMAL() { 067 super(); // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 068 format = new DecimalFormat( "#,##0.#" ); // 6.8.3.1 (2017/12/01) 069 defValue = ""; // 5.1.1.0 (2009/12/01) 070 noDisplayVal = null; // 5.5.1.0 (2012/04/03) 071 } 072 073 /** 074 * DBColumnオブジェクトを指定したprivateコンストラクター。 075 * 076 * @param clm DBColumnオブジェクト 077 * 078 * @og.rev 5.1.1.0 (2009/12/01) 初期値がnullの場合は、defValueはnullとする。 079 * @og.rev 5.6.2.3 (2013/03/22) noDisplayVal 変数追加 080 */ 081 private Renderer_DECIMAL( final DBColumn clm ) { 082 super(); // 6.4.1.1 (2016/01/16) PMD refactoring. It is a good practice to call super() in a constructor 083 084 String fm = clm.getRendererParam(); 085 if( fm == null || fm.isEmpty() || fm.equals( "_" ) ) { 086 fm = "#,##0.#"; 087 } 088 format = new DecimalFormat( fm ); 089 090 // 5.1.1.0 (2009/12/01) 091 final String defv = clm.getDefault(); 092 if( defv == null || defv.isEmpty() ) { 093 defValue = ""; 094 } 095 else { 096 final double dd = StringUtil.parseDouble( defv ); 097 defValue = format.format( dd ); 098 } 099 noDisplayVal = clm.getNoDisplayVal(); // 5.6.2.3 (2013/03/22) 100 } 101 102 /** 103 * 各オブジェクトから自分のインスタンスを返します。 104 * 自分自身をキャッシュするのか、新たに作成するのかは、各サブクラスの実装に 105 * まかされます。 106 * 107 * @og.rev 6.8.3.1 (2017/12/01) 標準オブジェクトとして、利用できる形にして、キャッシュします。 108 * 109 * @param clm DBColumnオブジェクト 110 * @return CellRendererオブジェクト 111 * @og.rtnNotNull 112 */ 113 public CellRenderer newInstance( final DBColumn clm ) { 114 // 6.8.3.1 (2017/12/01) 標準オブジェクトとして、利用できる形にして、キャッシュします。 115 116 final String fm = clm.getRendererParam(); 117 final String defv = clm.getDefault(); 118 119 if( ( fm == null || fm.isEmpty() || fm.equals( "_" ) ) && 120 ( defv == null || defv.isEmpty() || defv.equals( "_" ) ) ) { 121 return DB_CELL; 122 } 123 124 return new Renderer_DECIMAL( clm ); 125 } 126 127 /** 128 * データの表示用文字列を返します。 129 * 130 * ここでは、値が 0 の場合に、初期値を使うロジックが組み込まれており、 131 * 従来はこれを利用して、初期値にゼロ文字列を設定することで、"0" を 132 * 非表示文字として扱っていました。 133 * 互換性の問題があるので、既存の機能は残しますが、この処理は、noDisplayVal を 134 * 利用した処理に置き換えてください。 135 * 他の処理(NUMBER,MONEY,DBMENUなど)は、noDisplayVal を使います。 136 * 137 * @og.rev 3.8.5.2 (2006/05/31) カンマ編集された数字の対応 138 * @og.rev 5.3.1.0 (2009/12/01) 値が0の場合は、初期値を適用する。 139 * @og.rev 5.6.2.3 (2013/03/22) noDisplayVal 変数追加 140 * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化 141 * 142 * @param value 入力値 143 * @return データの表示用文字列 144 */ 145 @Override 146 public String getValue( final String value ) { 147 return getValue( value , true ); 148 } 149 150 /** 151 * データ出力用の文字列を作成します。 152 * ファイル等に出力する形式を想定しますので、HTMLタグを含まない 153 * データを返します。 154 * 基本は、#getValue( String ) をそのまま返します。 155 * 156 * @og.rev 6.0.4.0 (2014/11/28) データ出力用のレンデラー 157 * 158 * @param value 入力値 159 * @return データ出力用の文字列 160 * @see #getValue( String ) 161 */ 162 @Override 163 public String getWriteValue( final String value ) { 164 return getValue( value , false ); 165 } 166 167 /** 168 * データ表示用/出力用の文字列を作成します。 169 * 第二引数の isView == true で、データ表示用文字列を、false で 170 * データ出力用の文字列を作成します。 171 * 処理の共通化を行うためのメソッドです。 172 * 173 * @og.rev 6.0.4.0 (2014/11/28) ロジックの共通化 174 * 175 * @param value 入力値 176 * @param isView データ表示用かどうか(true:表示用/false:出力用) 177 * @return データ表示用/出力用の文字列 178 * @see #getValue( String ) 179 */ 180 private String getValue( final String value , final boolean isView ) { 181 // 5.6.2.3 (2013/03/22) noDisplayVal 変数追加 182 if( noDisplayVal != null && noDisplayVal.equalsIgnoreCase( value ) ) { return "" ; } 183 184 if( value == null || value.trim().isEmpty() || "0".equals( value ) ) { 185 return defValue; 186 } 187 188 final double dd = StringUtil.parseDouble( value ); 189 190 // 6.4.2.1 (2016/02/05) PMD refactoring. 191 final String rtn; 192 synchronized( format ) { 193 rtn = format.format( dd ); 194 } 195 196 return isView && dd < 0.0 197 ? "<span class=\"minus\">" + rtn + "</span>" 198 : rtn; 199 } 200 201 /** 202 * name属性を変えた、データ表示用のHTML文字列を作成します。 203 * レンデラーのため、row(行番号)は使いません。 204 * 第3引数に、パラメータを渡すことが出来ます。これは、viewMarker で 205 * [$XXXX param] 形式を渡すことで、行単位に表示形式を変更できます。 206 * 207 * @og.rev 6.8.3.1 (2017/12/01) パラメータを渡せるようにします。 208 * 209 * @param row 行番号 210 * @param value 値 211 * @param param パラメータ 212 * @return データ表示/編集用の文字列 213 */ 214 @Override 215 public String getValue( final int row,final String value,final String param ) { 216 // 5.6.2.3 (2013/03/22) noDisplayVal 変数追加 217 if( noDisplayVal != null && noDisplayVal.equalsIgnoreCase( value ) ) { return "" ; } 218 219 if( value == null || value.trim().isEmpty() || "0".equals( value ) ) { 220 return defValue; 221 } 222 223 final double dd = StringUtil.parseDouble( value ); 224 225 String fm = param; 226 if( fm == null || fm.isEmpty() || fm.equals( "_" ) ) { 227 fm = "#,##0.#"; 228 } 229 final DecimalFormat format = new DecimalFormat( fm ); 230 final String rtn = format.format( dd ); 231 232 return dd < 0.0 233 ? "<span class=\"minus\">" + rtn + "</span>" 234 : rtn; 235 } 236}