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.hayabusa.taglib; 017 018import java.io.File; 019import java.io.IOException; 020import java.io.Writer; 021import java.nio.charset.StandardCharsets; 022import java.nio.file.Files; 023import java.nio.file.Paths; 024import java.util.LinkedHashMap; 025import java.util.Locale; 026import java.util.Map; 027import java.util.Set; 028 029import org.opengion.fukurou.system.Closer; 030import org.opengion.fukurou.util.ArraySet; 031import org.opengion.fukurou.util.ErrorMessage; 032import org.opengion.fukurou.util.FileUtil; 033import org.opengion.fukurou.util.HttpConnect; 034import org.opengion.fukurou.util.JSONScan; 035import org.opengion.fukurou.util.StringUtil; 036import org.opengion.fukurou.util.ToString; 037import org.opengion.hayabusa.common.HybsSystem; 038import org.opengion.hayabusa.common.HybsSystemException; 039import org.opengion.hayabusa.db.DBColumn; 040import org.opengion.hayabusa.db.DBTableModel; 041import org.opengion.hayabusa.db.DBTableModelUtil; 042 043import static org.opengion.fukurou.util.StringUtil.nval; 044 045/** 046 * IOr (Information Organizer) に接続し、取得したデータベースを表示するタグです。 047 * 048 * IOr へデータ取得を要求して受取った JSON形式 の文字列を、DBTableModel にセットします。 049 * IOr から取得したデータより loadFile が優先されます。 050 * 051 * このタグの結果(DBTableModel)は、通常の QueryTag と同様に 052 * ViewFormTag で一覧表示や、WriteTableTag でファイル出力が可能です。 053 * 054 * SystemData の USE_SQL_INJECTION_CHECK が true か、quotCheck 属性が true の場合は、 055 * SQLインジェクション対策用のシングルクォートチェックを行います。リクエスト引数に 056 * シングルクォート(')が含まれると、エラーになります。 057 * 同様にUSE_XSS_CHECKがtrueか、xssCheck属性がtrueの場合は、 058 * クロスサイトススクリプティング(XSS)対策のためless/greater than signのチェックを行います。 059 * 060 * 実行後にリクエストパラメータに以下の値がセットされます。 061 * DB.COUNT : 実行結果の件数 062 * DB.ERR_CODE : 実行結果のエラーコード 063 * DB.ERR_MSG : 実行結果のエラーメッセージ 064 * 065 * ※ このタグは、Transaction タグの対象です。 066 * 067 * @og.formSample 068 * ●形式: 069 * <og:iorQuery 070 * url = "http://・・・ " 必須 071 * authURL = "http://・・・ " 必須 072 * authUserPass = "admin:******" 必須 073 * appliName = "データテーブル名" 074 * callMethod = "getReportInfo" 075 * /> 076 * 077 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します) 078 * 079 * ●Tag定義: 080 * <og:iorQuery 081 * url ○【TAG】アクセスする URL を指定します (必須) 082 * proxyHost 【TAG】プロキシ経由で接続する場合の、プロキシホスト名を指定します 083 * proxyPort 【TAG】プロキシ経由で接続する場合の、プロキシポート番号を指定します 084 * timeout 【TAG】通信リンクのオープン時に、指定された秒単位のタイム・アウト値を使用します 085 * (初期値:URL_CONNECT_TIMEOUT[={@og.value SystemData#URL_CONNECT_TIMEOUT}]) 086 * authURL ○【TAG】JSONコードで認証するURLを指定します (必須) 087 * authUserPass ○【TAG】Basic認証を使用して接続する場合のユーザー:パスワードを指定します (必須) 088 * companyId 【TAG】企業IDを指定します 089 * appliName 【TAG】アプリケーションの名前を指定します 090 * callMethod 【TAG】関数名を指定します 091 * display 【TAG】接続の結果を表示するかどうかを指定します (初期値:false) 092 * saveFile 【TAG】接続の結果をファイルに保存します 093 * loadFile 【TAG】ファイルからURL接続結果に相当するデータを読み取ります 094 * command 【TAG】コマンド (NEW,RENEW)をセットします 095 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します (初期値:session) 096 * displayMsg 【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します (初期値:VIEW_DISPLAY_MSG[=]) 097 * notfoundMsg 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します 098 * (初期値:MSG0077[対象データはありませんでした]) 099 * stopZero 【TAG】検索結果が0件のとき処理を続行するかどうか[true/false]を指定します (初期値:false[続行する]) 100 * tableId 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 101 * stopError 【TAG】処理エラーの時に処理を中止するかどうか[true/false]を設定します (初期値:true) 102 * dispError 【TAG】エラー時にメッセージを表示するか[true/false]を設定します。通常はstopErrorと併用 (初期値:true) 103 * quotCheck 【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します 104 * (初期値:USE_SQL_INJECTION_CHECK) 105 * xssCheck 【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します 106 * (初期値:USE_XSS_CHECK[=true]) 107 * mainTrans 【TAG】(通常は使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します (初期値:false) 108 * useBeforeHtmlTag 【TAG】処理時間(queryTime)などの情報出力[true:有効/false:無効]を指定します (初期値:true) 109 * useTimeView 【TAG】処理時間を表示する TimeView を表示するかどうかを指定します 110 * (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}]) 111 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します (初期値:null) 112 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します (初期値:null) 113 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます (初期値:判定しない) 114 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます (初期値:判定しない) 115 * caseIf 【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます (初期値:判定しない) 116 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します (初期値:false) 117 * 118 * > ... Body ... 119 * </og:iorQuery> 120 * 121 * ●使用例 122 * <og:iorQuery 123 * url = "http://・・・ " 124 * authURL = "http://・・・ " 125 * authUserPass = "admin:******" 126 * appliName = "データテーブル名" 127 * callMethod = "getReportInfo" 128 * > 129 * <og:iorQueryParam 130 * key = "where" value = "{'PN':'{@PN}%','TANI':'{@TANI}'}" /> 131 * </og:iorQueryParam 132 * </og:iorQuery ・・・・・ > 133 * 134 * @og.rev 8.0.2.0 (2021/11/30) 新規作成 135 * @og.group その他部品 136 * 137 * @version 8.0 138 * @author LEE.M 139 * @since JDK17.0, 140 */ 141public class IorQueryTag extends CommonTagSupport { 142 /** このプログラムのVERSION文字列を設定します。 {@value} */ 143 private static final String VERSION = "8.0.2.0 (2021/11/30)" ; 144 private static final long serialVersionUID = 802020211130L ; 145 146 /** command 引数に渡す事の出来る コマンド 新規 {@value} */ 147 public static final String CMD_NEW = "NEW"; // コマンド(新規) 148 /** command 引数に渡す事の出来る コマンド 再検索 {@value} */ 149 public static final String CMD_RENEW = "RENEW"; // コマンド(再検索) 150 // String配列 から、Setに置き換えます。 151 private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_NEW, CMD_RENEW ); // コマンド(Set) 152 153 protected static final String ERR_MSG_ID = HybsSystem.ERR_MSG_KEY; // エラーメッセージID 154 155 // IOr 応答結果のキー 156 private static final String IOR_HTTP_STTS = "status"; // ステータス 157 private static final String IOR_HTTP_MSG = "message"; // エラーメッセージ 158 protected static final String IOR_DISP_LBL = "display_label"; // ヘッダ配列のラベル 159 protected static final String IOR_DISP_KEY = "display"; // ヘッダ配列のキー 160 private static final String IOR_SQL_MSG = "information"; // 処理後メッセージ 161 private static final String IOR_SQL_CNT = "insert_count"; // 実行件数 162 163 // JSONによるフェーズ認証フォーマット 164 private static final String AUTH_JSON_FMT = "{\"userInfo\":{\"companyId\":\"%s\",\"userId\":\"%s\",\"password\":\"%s\"}}"; 165 166 protected final Map<String,String> mapParam = new LinkedHashMap<>(); // JSONコード 167 protected transient DBTableModel table; // テーブルモデル 168 169 private String urlStr ; // 接続するURL 170 private String proxyHost = HybsSystem.sys( "HTTP_PROXY_HOST" ); // プロキシホスト名 171 private int proxyPort = HybsSystem.sysInt( "HTTP_PROXY_PORT" ); // プロキシポート番号 172 private int timeout = HybsSystem.sysInt( "URL_CONNECT_TIMEOUT" ); // 接続タイムアウト時間 173 private String authURL ; // JSONコードで認証するURL 174 private String authUserPass ; // ユーザー:パスワード 175 private String companyId = HybsSystem.sys( "IOR_COMPANYID" ); // 企業ID 176 private String appliName ; // アプリ名 177 private String callMethod ; // 関数名 178 private boolean display ; // 結果の表示可否 179 private String saveFile ; // 保存ファイル 180 protected String loadFile ; // 読取ファイル 181 private String command = CMD_NEW; // コマンド 182 private String displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" ); // ディスプレイメッセージ 183 private String notfoundMsg = "MSG0077"; // 対象データはありませんでした。 184 private boolean stopZero ; // 処理の停止可否 185 protected String tableId = HybsSystem.TBL_MDL_KEY; // テーブルモデル 186 protected boolean stopError = true; // エラー時の処理中止可否 187 private boolean dispError = true; // 画面上のエラー出力可否 188 protected boolean quotCheck = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" ); // クオートチェック 189 private boolean xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // XSSチェック 190 private boolean useBeforeHtmlTag = true; // 処理時間(queryTime)などの情報出力の可否 191 protected boolean useTimeView = HybsSystem.sysBool( "VIEW_USE_TIMEBAR" ); // タイムバーの使用可否 192 193 private String user ; // ユーザー 194 private String pass ; // パスワード 195 protected String postData ; // BODY部 196 protected String rtnData ; // 取得データ 197 private int executeCount ; // 実行件数 198 protected long dyStart ; // 現在時刻 199 private boolean isMainTrans = true; // DBLastSqlの処理見直し 200 private String fileURL = HybsSystem.sys( "FILE_URL" ); // ファイルURL 201 202 /** 203 * デフォルトコンストラクター 204 * 205 */ 206 public IorQueryTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 207 208 /** 209 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 210 * 211 * @return 後続処理の指示 212 */ 213 @Override 214 public int doStartTag() { 215 if( !useTag() ) { return SKIP_BODY ; } 216 217 useXssCheck( xssCheck ); 218 dyStart = System.currentTimeMillis(); // 現在時刻 219 220 if( ! check( command, COMMAND_SET ) ) { 221 table = (DBTableModel)getObject( tableId ); 222 if( table == null ) { executeCount = 0; } 223 else { executeCount = table.getRowCount(); } 224 return SKIP_BODY; 225 } 226 227 useMainTrans( isMainTrans ); 228 startQueryTransaction( tableId ); 229 230 // scope="session" の場合のみ、削除します。 231 if( "session".equals( getScope() ) ) { 232 removeSessionAttribute( tableId ); 233 removeSessionAttribute( HybsSystem.VIEWFORM_KEY ); 234 } 235 236 // ユーザー:パスワード から ユーザーとパスワードを取得します。 237 checkUsrPw(); 238 239 // 読取ファイル指定無し 240 if( loadFile == null ) { 241 // JSON形式の共通要求キーを設定します。 242 setComJson(); 243 } 244 return EVAL_BODY_BUFFERED; // Body を評価する (extends BodyTagSupport 時) 245 } 246 247 /** 248 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。 249 * 250 * @return 後続処理の指示(SKIP_BODY) 251 */ 252 @Override 253 public int doAfterBody() { 254 // useQuotCheck() によるSQLインジェクション対策 255 useQuotCheck( quotCheck ); 256 257 postData = getBodyString(); 258 259 return SKIP_BODY; 260 } 261 262 /** 263 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 264 * 265 * @return 後続処理の指示 266 */ 267 @Override 268 public int doEndTag() { 269 debugPrint(); 270 if( !useTag() ) { return EVAL_PAGE ; } 271 272 int errCode = ErrorMessage.OK; // エラーコード 273 if( check( command, COMMAND_SET ) ) { 274 // URLに対して応答結果を取得します。 275 rtnData = outJson(); 276 277 // IOr の応答結果を特定のキーワードで分割します。 278 final SplitReqJson splitJson = new SplitReqJson( rtnData ); 279 final String rtnStts = splitJson.getSttsJson(); 280 281 // 応答結果のHTTPステータスコードを設定します。 282 errCode = getStatus( rtnStts ); 283 284 if( errCode == ErrorMessage.OK ) { 285 // テーブルモデル作成します。 286 table = makeDBTable( splitJson ); 287 288 // 処理後のメッセージを作成します。 289 errCode = makeMessage(); 290 } 291 } 292 293 final int rtnCode; 294 // 異常 295 if( errCode >= ErrorMessage.NG ) { 296 rtnCode = stopError ? SKIP_PAGE : EVAL_PAGE ; 297 } 298 // 正常/警告 299 else { 300 // 実行件数 = ゼロ 且つ stopZero = true 301 rtnCode = executeCount == 0 && stopZero ? SKIP_PAGE : EVAL_PAGE ; 302 } 303 304 // 処理時間(queryTime)などの情報出力の有効/無効を指定します。 305 if( useTimeView && useBeforeHtmlTag ) { 306 final long dyTime = System.currentTimeMillis() - dyStart; 307 jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" ); 308 } 309 return rtnCode; 310 } 311 312 /** 313 * タグリブオブジェクトをリリースします。 314 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 315 */ 316 @Override 317 protected void release2() { 318 super.release2(); 319 mapParam.clear(); // JSONコードのクリア 320 table = null; // テーブルモデル 321 urlStr = null; // 接続するURL 322 proxyHost = HybsSystem.sys( "HTTP_PROXY_HOST" ); // プロキシホスト名 323 proxyPort = HybsSystem.sysInt( "HTTP_PROXY_PORT" ); // プロキシポート番号 324 timeout = HybsSystem.sysInt( "URL_CONNECT_TIMEOUT" ); // 接続タイムアウト時間 325 authURL = null; // JSONコードで認証するURL 326 authUserPass = null; // ユーザー:パスワード 327 companyId = HybsSystem.sys( "IOR_COMPANYID" ); // 企業ID 328 appliName = null; // アプリ名 329 callMethod = null; // 関数名 330 display = false; // 結果の表示可否 331 saveFile = null; // 保存ファイル 332 loadFile = null; // 読取ファイル 333 command = CMD_NEW; // コマンド 334 displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" ); // ディスプレイメッセージ 335 notfoundMsg = "MSG0077"; // 対象データはありませんでした。 336 stopZero = false; // 処理の停止可否 337 tableId = HybsSystem.TBL_MDL_KEY; // テーブルモデル 338 stopError = true; // エラー時の処理中止可否 339 dispError = true; // 画面上のエラー出力可否 340 quotCheck = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" ); // クオートチェック 341 xssCheck = HybsSystem.sysBool( "USE_XSS_CHECK" ); // XSSチェック 342 useBeforeHtmlTag = true; // 処理時間(queryTime)などの情報出力の可否 343 useTimeView = HybsSystem.sysBool( "VIEW_USE_TIMEBAR" ); // タイムバーの使用可否 344 345 user = null; // ユーザー 346 pass = null; // パスワード 347 postData = null; // BODY部 348 rtnData = null; // 取得データ 349 executeCount = 0; // 実行件数 350 dyStart = 0; // 現在時刻 351 isMainTrans = true; // DBLastSqlの処理見直し 352 fileURL = HybsSystem.sys( "FILE_URL" ); // ファイルURL 353 } 354 355 /** 356 * IorQuery オブジェクトに渡すパラメータをマッピングします。 357 * 358 * IorQueryParamTag クラスよりセットされます。 359 * 但し、以下のキーに対して IorQueryParamTag では指定できません。 360 * company_id、user_id、session_id、report_name、method 361 * 362 * @param key パラメータキー 363 * @param val パラメータ値 364 */ 365 protected void addParam( final String key, final String val ) { 366 if( mapParam.containsKey( key ) ){ 367 final String errMsg = key + "のキーが重複しています。"; 368 throw new HybsSystemException( errMsg ); 369 } 370 else { 371 mapParam.put( key, val ); 372 } 373 } 374 375 /** 376 * ユーザー:パスワード から ユーザーとパスワードを分割します。 377 */ 378 protected void checkUsrPw() { 379 if( authUserPass.contains(":") ) { 380 // ユーザー:パスワードを分割します。 381 final String[] prm = StringUtil.csv2Array( authUserPass, ':' ,2 ); 382 user = prm[0]; // ユーザー 383 pass = prm[1]; // パスワード 384 } 385 else { 386 final String errMsg = "ユーザー:パスワード の形式で記述してください。"; 387 throw new HybsSystemException( errMsg ); 388 } 389 } 390 391 /** 392 * JSON形式の共通要求キーを設定します。 393 * ・company_id : 企業ID 394 * ・user_id : ユーザーID 395 * ・session_id : セッションID 396 * ・report_name : アプリ名 397 * ・method : メソッド 398 * 例:{"company_id":"XXXXX","user_id":"admin","session_id":"$session_id$" …} 399 */ 400 protected void setComJson() { 401 // 企業ID 402 if( companyId != null ) { mapParam.put( "company_id", companyId ); } 403 // ユーザーID 404 if( !user.isEmpty() ) { mapParam.put( "user_id", user ); } 405 // セッションID 406 mapParam.put( "session_id", "$session_id$" ); 407 // アプリ名 408 if( appliName != null ) { mapParam.put( "report_name", appliName ); } 409 // メソッド 410 if( callMethod != null ) { mapParam.put( "method", callMethod ); } 411 } 412 413 /** 414 * loadFile 指定がある場合は、ファイルからデータを読取ります。 415 * loadFile 指定がない場合は、URLに対して応答結果を取得します。 416 * 417 * @return JSON形式の文字列 418 * @og.rtnNotNull 419 */ 420 protected String outJson() { 421 final String str; 422 423 // 読取ファイル指定無し 424 if( loadFile == null ) { 425 if( postData == null || postData.isEmpty() ){ 426 postData = JSONScan.map2Json( mapParam ); 427 } 428 // URLに対して応答結果を取得します。 429 str = retResponse(); 430 } 431 // 読取ファイル指定有り 432 else { 433 final StringBuilder buf = new StringBuilder(BUFFER_MIDDLE); 434 try { 435 for (final String text : Files.readAllLines( Paths.get(loadFile), StandardCharsets.UTF_8 )) { 436 buf.append( text ) 437 .append( CR ); 438 } 439 str = buf.toString(); 440 } 441 catch( final IOException ex ) { 442 final String errMsg = "loadFile 処理中でエラーが発生しました。" + CR 443 + "\t " + ex.getMessage() + CR ; 444 throw new HybsSystemException( errMsg, ex ); 445 } 446 } 447 return str; 448 } 449 450 /** 451 * URLに対して応答結果を取得します。 452 * 453 * @return URL接続先のデータ 454 * @og.rtnNotNull 455 */ 456 protected String retResponse() { 457 HttpConnect conn = null; 458 Writer outWriter = null; 459 String getData = null; 460 try { 461 conn = connect(); 462 463 // URL接続先のデータを取得します。 464 getData = conn.readData(); 465 // 実行結果のステータスコードが'200'(正常)ではないとき、例外を発生させます。 466 if( conn.getCode() != 200 ) { throw new Throwable(); } 467 468 if( display ) { 469 outWriter = FileUtil.getNonFlushPrintWriter( pageContext.getOut() ) ; // JspWriter の取得 470 } 471 else if( saveFile != null ) { 472 outWriter = FileUtil.getPrintWriter( new File( saveFile ), "UTF-8" ); 473 } 474 475 // Unicode文字列から元の文字列に変換します。 476 getData = StringUtil.convertToOiginal( getData ); 477 478 // 出力先が存在する場合 479 if( outWriter != null ) { 480 outWriter.write( getData ); 481 } 482 } 483 catch( final Throwable th ) { 484 final String errMsg = "データ処理中にエラーが発生しました。" + CR 485 + " url=[" + urlStr + "]" + CR 486 + " message=[" + ( conn == null ? "NO_CONNECTION" : conn.getMessage() ) + "]" + CR 487 + " Exception=[" + th.getMessage() + "]" ; 488 throw new HybsSystemException( errMsg, th ); 489 } 490 finally { 491 Closer.ioClose( outWriter ); 492 } 493 return getData; 494 } 495 496 /** 497 * URLに対して接続を行います。 498 * 499 * @return 接続オブジェクト 500 * @og.rtnNotNull 501 * @throws IOException 入出力エラーが発生したとき 502 */ 503 protected HttpConnect connect() throws IOException { 504 // HttpConnect は、後付で引数を渡せます。 505 final HttpConnect conn = new HttpConnect( urlStr, authUserPass ); 506 conn.setDebug( isDebug() ); 507 conn.usePost( true ); 508 509 // プロキシ 510 if( proxyHost != null ) { 511 conn.setProxy( proxyHost,proxyPort ); 512 } 513 // JSONによるフェーズ認証 514 if( authUserPass != null && authURL != null ) { 515 final String authJson = String.format( AUTH_JSON_FMT, companyId, user, pass ) ; 516 conn.setAuthJson( authJson , authURL ); 517 } 518 // 接続タイムアウト時間 519 if( timeout >= 0 ) { 520 conn.setTimeout( timeout ); 521 } 522 // JSONコードでリクエストするパラメータを指定 523 if( postData != null ) { 524 conn.setReqJson( postData ); 525 } 526 return conn; 527 } 528 529 /** 530 * IOr の要求結果から、HTTPステータスコードを設定します。 531 * 532 * @param strJson Json形式の文字列 533 * @return エラーコード 534 * @og.rtnNotNull 535 */ 536 protected int getStatus( final String strJson ) { 537 int errCode = ErrorMessage.OK; // エラーコード 538 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); // バッファ 539 540 // --------------------------------------------------------------------- 541 // HTTPステータスコード (先頭から"data"までの文字列) 542 // 例:{"status": 200, "message": "OK", "sessionInfo": "51b16" 543 // --------------------------------------------------------------------- 544 // キーと値をマッピングします。 545 final Map<String,String> mapStts = JSONScan.json2Map( strJson ); 546 final String stts = mapStts.get( IOR_HTTP_STTS ); // ステータス 547 548 // ステータスが'200'(正常)である 549 if( stts.equals( String.valueOf( 200 ) ) ) { 550 errCode = ErrorMessage.OK; // 正常 551 displayMsg = " 件の" + mapStts.get( IOR_SQL_MSG ); // 処理メッセージ 552 executeCount = nval( mapStts.get( IOR_SQL_CNT ), -1 ); // 実行件数 553 554 // 実行結果がゼロ件の場合に画面上に表示します。 555 if( CMD_NEW.equals( command ) && executeCount == 0 556 && notfoundMsg != null && notfoundMsg.length() > 0 ) { 557 buf.append( getResource().getLabel( notfoundMsg ) ) 558 .append( BR ); 559 } 560 } 561 // ステータスが'200'(正常)ではない 562 else { 563 errCode = ErrorMessage.NG; // エラーコード 564 String msg = mapStts.get( IOR_HTTP_MSG ); // エラーメッセージ 565 // HTTPエラーではない 566 if( "NG".equalsIgnoreCase(msg) ) { msg = mapStts.get( IOR_SQL_MSG ); } // 処理メッセージ 567 568 final ErrorMessage errMessage = new ErrorMessage( "iorQueryTag Error!" ); 569 errMessage.addMessage( 0, errCode, stts, msg ); 570 571 // TaglibUtil.makeHTMLErrorTable メソッドを利用します。 572 final String err = TaglibUtil.makeHTMLErrorTable( errMessage, getResource() ); 573 if( err != null && err.length() > 0 ) { 574 buf.append( err ); 575 setSessionAttribute( ERR_MSG_ID, errMessage ); 576 } 577 // 以前処理のエラーメッセージを削除します。 578 else if( CMD_NEW.equals( command ) ) { 579 removeSessionAttribute( ERR_MSG_ID ); 580 } 581 } 582 583 final String label = buf.toString(); 584 // dispErrorで表示をコントロール 585 if( dispError ) { jspPrint( label ); } 586 587 // 検索結果の件数を、"DB.COUNT" キーでリクエストにセットします。 588 setRequestAttribute( "DB.COUNT" , String.valueOf( executeCount ) ); 589 // 検索結果を、"DB.ERR_CODE" キーでリクエストにセットします。 590 setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) ); 591 // エラーメッセージを、"DB.ERR_MSG" キーでリクエストにセットします。 592 setRequestAttribute( "DB.ERR_MSG", label ); 593 594 return errCode; 595 } 596 597 /** 598 * IOr の 要求結果から、値を取り出し、DBTableModel を作成します。 599 * 600 * @param strJson Json形式の文字列 601 * @return テーブルモデル 602 * @og.rtnNotNull 603 */ 604 private DBTableModel makeDBTable( final SplitReqJson strJson ) { 605 final DBTableModel table = DBTableModelUtil.newDBTable(); 606 607 // --------------------------------------------------------------------- 608 // テーブルモデルの列 ("headers"から"rows"までの文字列) 609 // 例:"headers": [{"display_label": "品目番号", "display": "PN"}, … ] 610 // --------------------------------------------------------------------- 611 final String rtnClm = strJson.getClmJson(); 612 613 // 中括弧({})で分割 614 final JSONScan scanClm = new JSONScan( rtnClm, '{', '}' ); 615 final int cntClm = scanClm.countBlock(); 616 table.init( cntClm ); 617 int i = 0; 618 619 while( scanClm.hasNext() ) { 620 final String clms = scanClm.next(); 621 622 // キーと値をマッピングします。 623 final Map<String,String> mapClm = JSONScan.json2Map( clms ); 624 final String clmLbl = mapClm.get( IOR_DISP_LBL ); // ラベル(例:品目番号) 625 final String clmKey = mapClm.get( IOR_DISP_KEY ); // キー(例:PN) 626 627 // テーブルモデルに列を追加します。 628 final DBColumn dbColumn = getResource().makeDBColumn( clmKey, clmLbl ); 629 table.setDBColumn( i++, dbColumn ); 630 } 631 632 // --------------------------------------------------------------------- 633 // テーブルモデルの行 ("cols"から最後の文字列) 634 // 例:"rows": [{"cols": [1, "GEN", "20211130", 32.4, "kg"]}, … ]}} 635 // --------------------------------------------------------------------- 636 final String rtnRow = strJson.getRowJson(); 637 638 // 大括弧([])で分割 639 final JSONScan scanRow = new JSONScan( rtnRow, '[', ']' ); 640 while( scanRow.hasNext() ) { 641 final String rows = scanRow.next(); 642 final String[] vals = JSONScan.json2Array( rows ); 643 // テーブルモデルに行の値を追加します。 644 table.addColumnValues( vals ); 645 } 646 return table; 647 } 648 649 /** 650 * 処理後のメッセージを作成します。 651 * 652 * @return エラーコード 653 * @og.rtnNotNull 654 */ 655 protected int makeMessage() { 656 int errCode = ErrorMessage.OK; // エラーコード 657 final ErrorMessage errMessage = new ErrorMessage( "iorQueryTag Error!" ); // エラーメッセージ 658 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); // バッファ 659 660 // 実行結果を画面上に表示します。 661 if( CMD_NEW.equals( command ) && executeCount > 0 662 && displayMsg != null && displayMsg.length() > 0 ) { 663 buf.append( executeCount ) 664 .append( getResource().getLabel( displayMsg ) ) 665 .append( BR ); 666 } 667 668 // 「ERR0041:検索処理中に割り込みの検索要求がありました」エラーを、標準のErrorMessageに追加するようにします。 669 if( table != null && ! commitTableObject( tableId, table ) ) { 670 // ERR0041:検索処理中に割り込みの検索要求がありました。処理されません。 671 errCode = ErrorMessage.NG; 672 errMessage.addMessage( 0, errCode, "ERR0041" ); 673 } 674 675 // TaglibUtil.makeHTMLErrorTable メソッドを利用します。 676 final String err = TaglibUtil.makeHTMLErrorTable( errMessage, getResource() ); 677 if( err != null && err.length() > 0 ) { 678 buf.append( err ); 679 setSessionAttribute( ERR_MSG_ID, errMessage ); 680 } 681 else if( CMD_NEW.equals( command ) ) { 682 removeSessionAttribute( ERR_MSG_ID ); 683 } 684 final String label = buf.toString(); 685 // dispErrorで表示をコントロール 686 if( dispError ) { jspPrint( label ); } 687 688 // 検索結果を、"DB.ERR_CODE" キーでリクエストにセットします。 689 setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) ); 690 // エラーメッセージを、"DB.ERR_MSG" キーでリクエストにセットします。 691 setRequestAttribute( "DB.ERR_MSG", label ); 692 693 return errCode; 694 } 695 696 /** 697 * 【TAG】アクセスする接続先URLを指定します。 698 * 699 * @og.tag 700 * 接続するURLを指定します。(例:http:// ・・・・・・) 701 * 702 * @param url 接続先 703 */ 704 public void setUrl( final String url ) { 705 urlStr = nval( getRequestParameter( url ),urlStr ); 706 } 707 708 /** 709 * 【TAG】プロキシ経由で接続する場合の、プロキシホスト名を指定します。 710 * 711 * @og.tag 712 * 接続先が、プロキシ経由の場合、プロキシのホスト名を指定します。 713 * 例:proxy.opengion.org 714 * 715 * @param host プロキシホスト名 716 */ 717 public void setProxyHost( final String host ) { 718 proxyHost = nval( getRequestParameter( host ),proxyHost ); 719 } 720 721 /** 722 * 【TAG】プロキシ経由で接続する場合の、プロキシポート番号を指定します。 723 * 724 * @og.tag 725 * 接続先が、プロキシ経由の場合、プロキシのポート番号を指定します。 726 * 例:8080 727 * 728 * @param port プロキシポート番号 729 */ 730 public void setProxyPort( final String port ) { 731 proxyPort = nval( getRequestParameter( port ),proxyPort ); 732 } 733 734 /** 735 * 【TAG】接続タイムアウト時間を(秒)で指定します 736 * (初期値:URL_CONNECT_TIMEOUT[={@og.value SystemData#URL_CONNECT_TIMEOUT}])。 737 * 738 * @og.tag 739 * 実際には、java.net.URLConnection#setConnectTimeout(int) に 1000倍して設定されます。 740 * 0 は、無限のタイムアウト、マイナスは、設定しません。(つまりJavaの初期値のまま) 741 * (初期値:システム定数のURL_CONNECT_TIMEOUT[={@og.value SystemData#URL_CONNECT_TIMEOUT}])。 742 * 743 * @param tout タイムアウト時間(秒) (ゼロは、無制限) 744 * @see org.opengion.fukurou.util.HttpConnect#setTimeout(int) 745 * @see java.net.URLConnection#setConnectTimeout(int) 746 */ 747 public void setTimeout( final String tout ) { 748 timeout = nval( getRequestParameter( tout ),timeout ); 749 } 750 751 /** 752 * 【TAG】JSONコードで認証するURLを指定します。 753 * 754 * @og.tag 755 * JSONコードで認証するURLを指定します。 756 * 757 * @param url JSONコードで認証するURL 758 */ 759 public void setAuthURL( final String url ) { 760 authURL = nval( getRequestParameter( url ), authURL ); 761 } 762 763 /** 764 * 【TAG】Basic認証を使用して接続する場合のユーザー:パスワードを指定します。 765 * 766 * @og.tag 767 * 接続時のユーザーとパスワードを、USER:PASSWD 形式で指定します。 768 * 769 * @param userPass ユーザーとパスワード (USER:PASSWD形式) 770 */ 771 public void setAuthUserPass( final String userPass ) { 772 authUserPass = nval( getRequestParameter( userPass ),authUserPass ); 773 } 774 775 /** 776 * 【TAG】企業IDを指定します。 777 * 778 * @og.tag 779 * 企業IDを指定します。 780 * 781 * @param compId 企業ID 782 */ 783 public void setCompanyId( final String compId ) { 784 companyId = nval( getRequestParameter( compId ),companyId ); 785 } 786 787 /** 788 * 【TAG】アプリケーションの名前を指定します。 789 * 790 * @og.tag 791 * アプリケーションの名前を指定します。 792 * 793 * @param appName データテーブル情報 794 */ 795 public void setAppliName( final String appName ) { 796 appliName = nval( getRequestParameter( appName ),appliName ); 797 } 798 799 /** 800 * 【TAG】関数名を指定します。 801 * 802 * @og.tag 803 * 関数名を指定します。 804 * 805 * @param callMh 関数名 806 */ 807 public void setCallMethod( final String callMh ) { 808 callMethod = nval( getRequestParameter( callMh ),callMethod ); 809 } 810 811 /** 812 * 【TAG】接続の結果を表示するかどうかを指定します(初期値:false)。 813 * 814 * @og.tag 815 * true で、接続結果を表示します。 false では、何も表示しません(初期値:false) 816 * 接続結果を表示する使い方より、admin 画面に接続して、キャッシュクリアするような 817 * 使い方が多いと考え、初期値は、false になっています。 818 * display="true" と、saveFile を併用することはできません。 819 * 820 * @param flag 結果表示 [true:する/false:しない] 821 * @see #setSaveFile( String ) 822 */ 823 public void setDisplay( final String flag ) { 824 display = nval( getRequestParameter( flag ),display ); 825 826 if( display && saveFile != null ) { 827 final String errMsg = "display=\"true\" と、saveFile を併用することはできません。"; 828 throw new HybsSystemException( errMsg ); 829 } 830 } 831 832 /** 833 * 【TAG】接続の結果をファイルに保存します。 834 * 835 * @og.tag 836 * 接続先のデータを受け取って、ファイルに保存します。 837 * display="true" と、saveFile を併用することはできません。 838 * loadFile が指定されていない時のみ処理を行います。 839 * 840 * @param file 保存先ファイル 841 * @see #setDisplay( String ) 842 */ 843 public void setSaveFile( final String file ) { 844 saveFile = nval( getRequestParameter( file ),saveFile ); 845 if( saveFile != null ) { 846 saveFile = HybsSystem.url2dir( StringUtil.urlAppend( fileURL,saveFile ) ); 847 if( display ) { 848 final String errMsg = "display=\"true\" と、saveFile を併用することはできません。"; 849 throw new HybsSystemException( errMsg ); 850 } 851 } 852 } 853 854 /** 855 * 【TAG】ファイルからURL接続結果に相当するデータを読み取ります。 856 * 857 * @og.tag 858 * 主にデバッグ用として使われます。 859 * 860 * @param file 検索するファイル 861 */ 862 public void setLoadFile( final String file ) { 863 loadFile = nval( getRequestParameter( file ),loadFile ); 864 if( loadFile != null ) { 865 loadFile = HybsSystem.url2dir( StringUtil.urlAppend( fileURL,loadFile ) ); 866 } 867 } 868 869 /** 870 * 【TAG】コマンド (NEW,RENEW)をセットします。 871 * 872 * @og.tag 873 * コマンドは、HTMLから(get/post)指定されますので、 874 * CMD_xxx で設定されるフィールド定数値のいづれかを指定できます。 875 * 876 * @param cmd コマンド (public static final 宣言されている文字列) 877 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.QueryTag.CMD_NEW">コマンド定数</a> 878 */ 879 public void setCommand( final String cmd ) { 880 final String cmd2 = getRequestParameter( cmd ); 881 if( cmd2 != null && cmd2.length() >= 0 ) { command = cmd2.toUpperCase( Locale.JAPAN ); } 882 } 883 884 /** 885 * 【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します 886 * (初期値:VIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])。 887 * 888 * @og.tag 889 * ここでは、検索結果の件数や登録された件数をまず出力し、 890 * その次に、ここで指定したメッセージをリソースから取得して表示します。 891 * 件数を表示させる場合は、displayMsg = "MSG0033"[ 件検索しました] をセットしてください。 892 * 表示させたくない場合は, displayMsg = "" をセットしてください。 893 * (初期値:システム定数のVIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])。 894 * 895 * @param id 表示メッセージID 896 * @see org.opengion.hayabusa.common.SystemData#VIEW_DISPLAY_MSG 897 */ 898 public void setDisplayMsg( final String id ) { 899 final String ids = getRequestParameter( id ); 900 if( ids != null ) { displayMsg = ids; } 901 } 902 903 /** 904 * 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。 905 * 906 * @og.tag 907 * ここでは、検索結果がゼロ件の場合のみ、特別なメッセージを表示させます。 908 * 従来は、displayMsg と兼用で、『0 件検索しました』という表示でしたが、 909 * displayMsg の初期表示は、OFF になりましたので、ゼロ件の場合のみ別に表示させます。 910 * 表示させたくない場合は, notfoundMsg = "" をセットしてください。 911 * 初期値は、MSG0077[対象データはありませんでした]です。 912 * 913 * @param id ゼロ件メッセージID 914 */ 915 public void setNotfoundMsg( final String id ) { 916 final String ids = getRequestParameter( id ); 917 if( ids != null ) { notfoundMsg = ids; } 918 } 919 920 /** 921 * 【TAG】検索結果が0件のとき処理を停止するかどうか[true/false]を指定します(初期値:false[続行する])。 922 * 923 * @og.tag 924 * 初期値は、false(続行する)です。 925 * 926 * @param flag 0件時停止可否 [true:処理を中止する/false:続行する] 927 */ 928 public void setStopZero( final String flag ) { 929 stopZero = nval( getRequestParameter( flag ),stopZero ); 930 } 931 932 /** 933 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 934 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 935 * 936 * @og.tag 937 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 938 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 939 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 940 * この tableId 属性を利用して、メモリ空間を分けます。 941 *(初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。 942 * 943 * @param id テーブルID (sessionに登録する時のID) 944 */ 945 public void setTableId( final String id ) { 946 tableId = nval( getRequestParameter( id ),tableId ); 947 } 948 949 /** 950 * 【TAG】処理エラーの時に処理を中止するかどうか[true/false]を設定します(初期値:true)。 951 * 952 * @og.tag 953 * false(中止しない)に設定する場合、後続処理では、{@DB.ERR_CODE}の値により、 954 * IOr の異常/正常終了によって分岐処理は可能となります。 955 * 初期値は、true(中止する)です。 956 * 957 * @param flag エラー時処理中止 [true:中止する/false:中止しない] 958 */ 959 public void setStopError( final String flag ) { 960 stopError = nval( getRequestParameter( flag ),stopError ); 961 } 962 963 /** 964 * 【TAG】PLSQL/SQL処理エラーの時にエラーを画面表示するか[true/false]を設定します(初期値:true)。 965 * 966 * @og.tag 967 * false(表示しない)に設定する場合、後続処理では、{@DB.ERR_MSG}の値により、 968 * 本来表示されるはずだったメッセージを取得可能です。 969 * stopErrorと併用して、JSON形式でエラーを返す場合等に利用します。 970 * 初期値は、true(表示する)です。 971 * ※false指定の場合は件数や、overFlowメッセージ等も表示されなくなります。 972 * 973 * @param flag [true:表示する/false:表示しない] 974 */ 975 public void setDispError( final String flag ) { 976 dispError = nval( getRequestParameter( flag ),dispError ); 977 } 978 979 /** 980 * 【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します 981 * (初期値:USE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])。 982 * 983 * @og.tag 984 * SQLインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに 985 * 渡す文字列にシングルクォート(') を許さない設定にすれば、ある程度は防止できます。 986 * 数字タイプの引数には、 or 5=5 などのシングルクォートを使用しないコードを埋めても、 987 * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、 988 * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。 989 * (') が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 990 * 初期値は、SystemData#USE_SQL_INJECTION_CHECK です。 991 * 992 * @param flag クォートチェック [true:する/それ以外:しない] 993 */ 994 public void setQuotCheck( final String flag ) { 995 quotCheck = nval( getRequestParameter( flag ),quotCheck ); 996 } 997 998 /** 999 * 【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します 1000 * (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。 1001 * 1002 * @og.tag 1003 * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。 1004 * (><) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。 1005 * (初期値:システム定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}]) 1006 * 1007 * @param flag XSSチェック [true:する/false:しない] 1008 * @see org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK 1009 */ 1010 public void setXssCheck( final String flag ) { 1011 xssCheck = nval( getRequestParameter( flag ),xssCheck ); 1012 } 1013 1014 /** 1015 * 【TAG】(通常は使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:true)。 1016 * 1017 * @og.tag 1018 * この値は、ファイルダウンロード処理に影響します。この値がtrueに指定された時にcommitされたDBTableModelが 1019 * ファイルダウンロードの対象の表になります。 1020 * 1021 * このパラメーターは、通常、各タグにより実装され、ユーザーが指定する必要はありません。 1022 * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてファイルダウンロードをさせたい 1023 * 場合は、後ろでDBTableModelを生成するタグで、明示的にこの値をfalseに指定することで、ファイルダウンロード処理の対象から 1024 * 除外することができます。 1025 * 1026 * @param flag メイントランザクションかどうか [true:メイン/false:その他] 1027 */ 1028 public void setMainTrans( final String flag ) { 1029 isMainTrans = nval( getRequestParameter( flag ),isMainTrans ); 1030 } 1031 1032 /** 1033 * 【TAG】 処理時間(queryTime)などの情報出力[true:有効/false:無効]を指定します(初期値:true)。 1034 * 1035 * @og.tag 1036 * Query で、検索する場合に、処理時間(queryTime)などの情報を出力していますが、 1037 * ViewForm で、CustomData などの 非HTML表示ビューを使用する場合、データとして、 1038 * 紛れ込んでしまうため、出力を抑制する必要があります。 1039 * true(有効)にすると、これらのHTMLが出力されます。false にすると、出力されません。 1040 * 初期値は、true(有効) です。 1041 * 1042 * @param useTag 情報出力の有効/無効 [true:有効/false:無効] 1043 */ 1044 public void setUseBeforeHtmlTag( final String useTag ) { 1045 useBeforeHtmlTag = nval( getRequestParameter( useTag ),useBeforeHtmlTag ); 1046 } 1047 1048 /** 1049 * 【TAG】処理時間を表示する TimeView を表示するかどうか[true:する/false:しない]を指定します 1050 * (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。 1051 * 1052 * @og.tag 1053 * true に設定すると、処理時間を表示するバーイメージが表示されます。 1054 * これは、DB検索、APサーバー処理、画面表示の各処理時間をバーイメージで 1055 * 表示させる機能です。処理時間の目安になります。 1056 * (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。 1057 * 1058 * @param flag 処理時間を表示 [true:する/false:しない] 1059 */ 1060 public void setUseTimeView( final String flag ) { 1061 useTimeView = nval( getRequestParameter( flag ),useTimeView ); 1062 } 1063 1064 /** 1065 * IOr の応答結果を特定のキーワードで分割します。(内部クラス) 1066 * 1067 * フォーマット形式のチェック と データの切り出しを行います。 1068 * JSONフォーマットの例:{"status": … "data": {"headers": [ … ], "rows": [ {cols:[ … ]} ]}} 1069 */ 1070 private static final class SplitReqJson { 1071 private final String strJson; // JSON形式の文字列 1072 private int endPos; // 終了位置 1073 1074 /** 1075 * コンストラクター 1076 * 1077 * @param strJson JSON形式の文字列 1078 */ 1079 public SplitReqJson( final String str ) { 1080 strJson = str; // JSON形式の文字列 1081 endPos = strJson.indexOf( "\"data\"" ); // 終了位置 1082 } 1083 1084 /** 1085 * HTTPステータス(先頭から "data"まで) の文字列を返します。 1086 * 1087 * @return JSON形式の文字列 1088 */ 1089 public String getSttsJson() { 1090 if( endPos >= 0 ) { 1091 return strJson.substring( 0, endPos ); 1092 } else { 1093 final String errMsg = "data キーが存在しません。"; 1094 throw new HybsSystemException( errMsg ); 1095 } 1096 } 1097 1098 /** 1099 * 列データ("headers"から "rows"まで) の文字列を返します。 1100 * 1101 * @return JSON形式の文字列 1102 */ 1103 public String getClmJson() { 1104 final int startPos = strJson.indexOf( "\"headers\"", endPos ); // 開始位置 1105 endPos = strJson.indexOf( "\"rows\"", startPos ); // 終了位置 1106 if( startPos >= 0 && endPos >= 0) { 1107 return strJson.substring( startPos, endPos ); 1108 } else { 1109 final String errMsg = "headers、rows キーのいずれかが存在しません。"; 1110 throw new HybsSystemException( errMsg ); 1111 } 1112 } 1113 1114 /** 1115 * 行データ("cols"から 最後まで) の文字列を返します。 1116 * 1117 * @return JSON形式の文字列 1118 */ 1119 public String getRowJson() { 1120 final int startPos = strJson.indexOf( "\"cols\"", endPos ); // 開始位置 1121 if( startPos >= 0 ) { 1122 return strJson.substring( startPos ); 1123 } else { 1124 final String errMsg = "cols キーが存在しません。"; 1125 throw new HybsSystemException( errMsg ); 1126 } 1127 } 1128 } 1129 1130 /** 1131 * このオブジェクトの文字列表現を返します。 1132 * 基本的にデバッグ目的に使用します。 1133 * 1134 * @return このクラスの文字列表現 1135 * @og.rtnNotNull 1136 */ 1137 @Override 1138 public String toString() { 1139 return ToString.title( this.getClass().getName() ) 1140 .println( "VERSION" ,VERSION ) 1141 .println( "urlStr" ,urlStr ) 1142 .println( "timeout" ,timeout ) 1143 .println( "authURL" ,authURL ) 1144 .println( "authUserPass" ,authUserPass ) 1145 .println( "companyId" ,companyId ) 1146 .println( "appliName" ,appliName ) 1147 .println( "callMethod" ,callMethod ) 1148 .println( "display" ,display ) 1149 .println( "postData" ,postData ) 1150 .println( "saveFile" ,saveFile ) 1151 .println( "loadFile" ,loadFile ) 1152 .println( "tableId" ,tableId ) 1153 .println( "Other..." ,getAttributes().getAttribute() ) 1154 .fixForm().toString() ; 1155 } 1156}