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.view; 017 018import org.opengion.fukurou.util.StringUtil; 019import org.opengion.hayabusa.html.AbstractViewForm; 020import org.opengion.hayabusa.html.ViewJsonParam; 021 022/** 023 * 検索結果を自動的に表形式に変換する、テーブル作成クラスです。 024 * 025 * ユーザー単位に表示するカラムの順番、表示可非を指定できるように対応します。 026 * setColumnDisplay( final String columnName ) に、指定された順番に 027 * 表示するというHTMLFormatTable の簡易版として用意します。 028 * 各HTMLのタグに必要な setter/getterメソッドのみ、追加定義しています。 029 * 030 * AbstractViewForm を継承している為、ロケールに応じたラベルを出力させる事が出来ます。 031 * 032 * @og.group 画面表示 033 * @og.rev 5.1.7.0 (2016/04/01) 新規作成 034 * 035 * @version 5.0 036 * @author Takahashi Masakazu 037 * @since JDK5.0, 038 */ 039public class ViewForm_JSON extends AbstractViewForm { 040 /** このプログラムのVERSION文字列を設定します。 {@value} */ 041 private static final String VERSION = "6.8.3.1 (2017/12/01)" ; 042 043 private int clmCnt = -1; 044 045// private String viewClms ; // 6.9.8.0 (2018/05/28) FindBugs:書き込まれていないフィールド 046 047 private String dataName; 048 private boolean useHead; 049 private boolean useInfo; 050 private boolean useRenderer; 051 private boolean useNullOmit; // 6.7.7.0 (2017/03/31) 052 private boolean useZeroOmit; // 6.7.7.0 (2017/03/31) 053 private boolean useEqValOmit; // 6.8.3.0 (2017/11/27) 054 // private boolean useUtfEncode; // '\u0000'形式への変換は仕様上必須ではないので現時点では実装しない 055 056 private String rendererCols; // 5.9.27.0 (2017/12/01) 057 058 /** ヘッダー部分のキャッシュ変数 */ 059 protected String headerLine; 060 061 /** 062 * デフォルトコンストラクター 063 * 064 * @og.rev 6.4.9.1 (2016/08/05) Each class should declare at least one constructor 065 */ 066 public ViewForm_JSON() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 067 068 /** 069 * DBTableModel から HTML文字列を作成して返します。 070 * startNo(表示開始位置)から、pageSize(表示件数)までのView文字列を作成します。 071 * 表示残りデータが pageSize 以下の場合は、残りのデータをすべて出力します。 072 * 073 * @og.rev 5.5.4.2 (2012/07/13) editName指定時の編集対応 074 * @og.rev 6.8.3.0 (2017/11/27) 処理速度向上(カラムのキャッシュ)と、同一値のomit処理(useEqValOmit)。 075 * @og.rev 6.8.3.1 (2017/12/01) nullの場合、useNullOmit || useZeroOmit と、useEqValOmit の useRenderer 対応 076 * @og.rev 5.9.17.0 (2017/12/01) レンデラー利用カラム追加 077 * 078 * @param startNo 表示開始位置 079 * @param pageSize 表示件数 080 * 081 * @return DBTableModelから作成された HTML文字列 082 */ 083 @Override 084 public String create( final int startNo, final int pageSize ) { 085 //if( getRowCount() == 0 ) { return ""; } // 暫定処置 086 087 paramInit(); 088 089 // 5.9.27.0 (2017/12/01) レンデラー利用カラムの指定(JSONのみの特殊判定) 090 final boolean[] rendCols = new boolean[clmCnt]; 091 // Arrays.fill( rendCols ,false ); 092 setBooleanArray( rendererCols,true,rendCols ); 093 094 headerLine = null; 095 final int lastNo = getLastNo( startNo, pageSize ); 096 097 final StringBuilder out = new StringBuilder( BUFFER_LARGE ); 098 099 // 6.8.3.0 (2017/11/27) 処理速度向上(カラムのキャッシュ) 100 final String[] clms = new String[clmCnt]; 101 final String[] oldDiff = new String[clmCnt]; // 6.8.3.1 (2017/12/01) 一つ前と比較するための変数 102 final String[] oldVals = new String[clmCnt]; // useRenderer が加味された値 103 for(int clm = 0; clm < clmCnt; clm++) { 104 clms[clm] = "\"" + getColumnName( clm ) + "\":\"" ; 105 } 106 107 //JSON開始 108 out.append( '{' ).append( CR ); 109 110 int rowcnt = 0; 111 out.append( '"' ).append( dataName ).append( "\":[" ); 112 for( int row=startNo; row<lastNo; row++ ) { 113 if( isSkip( row ) || isSkipNoEdit( row ) ) { continue; } 114 if(rowcnt > 0 ){ out.append( ',' ); } 115 rowcnt++; 116 out.append( '{' ); 117 118 int clmcount = 0; 119 for(int clm = 0; clm < clmCnt; clm++) { 120 121 if( isColumnDisplay( clm ) ) { // 6.8.3.0 (2017/11/27) continue 処理を囲う形で前に持ってきます。 122 // 6.7.7.0 (2017/03/31) 123 final String val = getValue( row,clm ); 124 125 if( ( val == null || val.isEmpty() ) && ( useNullOmit || useZeroOmit ) || 126 ( "0".equals( val ) || "0.0".equals( val ) || "0.00".equals( val ) ) && useZeroOmit || 127 val.equals( oldDiff[clm] ) && useEqValOmit ) { continue; } // 6.8.3.0 (2017/11/27) 同一値のomit処理(useEqValOmit) 追加 128 129 oldDiff[clm] = val; // 6.8.3.0 (2017/11/27) 同一値のomit処理(useEqValOmit) 追加 130 oldVals[clm] = StringUtil.jsonFilter( // 6.8.3.1 (2017/12/01) 131 useRenderer || rendCols[clm] ? getValueLabel(row,clm) : val // 5.9.27.0 (2017/12/01) 132 ); 133 134 if( clmcount > 0 ){ out.append( ',' );} 135 clmcount++; 136 137 out.append( clms[clm] ) // 6.8.3.1 (2017/12/01) 138 .append( oldVals[clm] ) 139 .append( '"' ); 140 } 141 } 142 out.append( '}' ); 143 } 144 145 // 6.8.3.0 (2017/11/27) 同一値のomit処理(useEqValOmit) 追加の後処理 146 if( useEqValOmit ) { 147 out.append( ",{" ); 148 int clmcount = 0; 149 for(int clm = 0; clm < clmCnt; clm++) { 150 if( isColumnDisplay( clm ) ) { 151 if( clmcount > 0 ){ out.append( ',' );} 152 clmcount++; 153 out.append( clms[clm] ) 154 .append( oldVals[clm] ) 155 .append( '"' ); 156 } 157 } 158 out.append( '}' ); 159 } 160 161 out.append( ']' ).append( CR ); 162 163 if( useHead ){ 164 out.append( ',' ).append( getHeader() ).append( CR ); 165 } 166 if( useInfo ){ 167 out.append( ',' ).append( getInfo(rowcnt) ).append( CR ); 168 } 169 170 //JSON終わり 171 out.append( '}' ).append( CR ); 172 173 return out.toString(); 174 } 175 176 /** 177 * パラメータ内容を初期化します。 178 * 179 * @og.rev 6.7.7.0 (2017/03/31) ViewJsonParam属性を、文字列から、boolean に変更 180 * @og.rev 6.8.3.0 (2017/11/27) useEqValOmit属性の追加 181 * @og.rev 5.9.17.0 (2017/12/01) レンデラー利用カラム追加 182 * 183 */ 184 private void paramInit() { 185 dataName = getParam( ViewJsonParam.JSON_DATANAME_KEY , ViewJsonParam.JSON_DATANAME ); 186 useHead = StringUtil.nval( getParam( ViewJsonParam.JSON_HEAD_KEY ) , ViewJsonParam.USE_JSON_HEAD ); 187 useInfo = StringUtil.nval( getParam( ViewJsonParam.JSON_INFO_KEY ) , ViewJsonParam.USE_JSON_INFO ); 188 useRenderer = StringUtil.nval( getParam( ViewJsonParam.JSON_RENDERER_KEY ) , ViewJsonParam.USE_JSON_RENDERER ); 189 useNullOmit = StringUtil.nval( getParam( ViewJsonParam.JSON_NULLOMIT_KEY ) , ViewJsonParam.USE_JSON_NULLOMIT ); // 6.7.7.0 (2017/03/31) 190 useZeroOmit = StringUtil.nval( getParam( ViewJsonParam.JSON_ZEROOMIT_KEY ) , ViewJsonParam.USE_JSON_ZEROOMIT ); // 6.7.7.0 (2017/03/31) 191 useEqValOmit= StringUtil.nval( getParam( ViewJsonParam.JSON_EQVALOMIT_KEY ) , ViewJsonParam.USE_JSON_EQVALOMIT); // 6.8.3.0 (2017/11/27) 192 // useUtfEncode= StringUtil.nval( getParam( ViewJsonParam.JSON_UTF_ENCODE ) , ViewJsonParam.USE_JSON_UTFENC ); 193 194 rendererCols= getParam( ViewJsonParam.JSON_RENDERER_COLS_KEY , ViewJsonParam.JSON_RENDERER_COLS ); // 5.9.17.0 (2017/12/01) 195 196 clmCnt = getColumnCount(); 197 } 198 199 /** 200 * DBTableModel から テーブルのヘッダータグ文字列を作成して返します。 201 * 202 * @return テーブルのヘッダータグ文字列 203 */ 204 protected String getHeader() { 205 return "\"HEAD\":{" + getTableHead() + "}"; 206 } 207 208 /** 209 * DBTableModel から テーブルのタグ文字列を作成して返します。 210 * 211 * @return テーブルのタグ文字列 212 */ 213 protected String getTableHead() { 214 return getHeadLine(); 215 } 216 217 /** 218 * ヘッダー繰り返し部を、getTableHead()メソッドから分離。 219 * 220 * @return テーブルのタグ文字列 221 */ 222 protected String getHeadLine() { 223 // 8.5.5.1 (2024/02/29) PMD 7.0.0 OnlyOneReturn メソッドには終了ポイントが 1 つだけ必要 224// if( headerLine != null ) { return headerLine; } // キャッシュを返す。 225 226 if( headerLine == null ) { 227 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 228 229 for(int clm = 0; clm < clmCnt; clm++) { 230 if( isColumnDisplay( clm ) ) { 231 if( buf.length() > 0 ){ buf.append( ',' ); } 232 buf.append( '"' ) 233 .append( getColumnName( clm ) ) 234 .append( "\":\"" ) 235 .append( StringUtil.jsonFilter( getColumnLabel( clm ) ) ) 236 .append( '"' ); 237 } 238 } 239 headerLine = buf.toString(); 240 } 241 242 return headerLine; 243 } 244 245 /** 246 * DBTableModel から テーブルのヘッダータグ文字列を作成して返します。 247 * 248 * @param rowcount 行番号 249 * 250 * @return テーブルのヘッダータグ文字列 251 */ 252 protected String getInfo( final int rowcount ) { 253 return new StringBuilder( BUFFER_MIDDLE ) 254 .append( "\"INFO\":{\"COUNT\":\"" ) 255 .append( rowcount ) 256 .append( "\"}") 257 .toString(); 258 } 259 260// /** 261// * ビューで表示したカラムの一覧をCSV形式で返します。 262// * 263// * @og.rev 5.1.6.0 (2010/05/01) 新規追加 264// * @og.rev 5.8.6.0 (2015/04/03) オリジナルカラム対応 265// * @og.rev 6.9.8.0 (2018/05/28) FindBugs:書き込まれていないフィールド 266// * 267// * @return ビューで表示したカラムの一覧 268// */ 269// @Override 270// public String getViewClms() { 271// // 一旦、削除しておきます。 272// if( viewClms == null ) { return super.getViewClms(); } 273// return viewClms; 274// } 275 276 /** 277 * フォーマットメソッドを使用できるかどうかを問い合わせます。 278 * 279 * @return 使用可能(true)/ 使用不可能(false) 280 */ 281 public boolean canUseFormat() { 282 return false; 283 } 284}