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 org.opengion.fukurou.system.Closer;                                                              // 6.4.2.1 (2016/02/05)
019import org.opengion.fukurou.db.ConnectionFactory;
020import org.opengion.fukurou.db.ResultSetValue;                                                  // 6.0.4.0 (2014/11/28)
021import org.opengion.fukurou.util.ToString;                                                              // 6.1.1.0 (2015/01/17)
022import org.opengion.hayabusa.common.HybsSystemException;
023import static org.opengion.fukurou.util.StringUtil.nval ;
024import static org.opengion.fukurou.system.HybsConst.BR;                                 // 6.1.0.0 (2014/12/26) refactoring
025import static org.opengion.fukurou.system.HybsConst.BUFFER_LARGE;               // 6.1.0.0 (2014/12/26) refactoring
026
027import java.util.ArrayList;
028
029import java.sql.DatabaseMetaData ;
030import java.sql.Connection;
031import java.sql.ResultSet;
032import java.sql.SQLException;
033import java.sql.Types;
034
035/**
036 * DatabaseMetaData の情報を検索するタグです。
037 *
038 * データベースに関する包括的な情報を提供する、DatabaseMetaData の内容を
039 * 表示する、タグです。テスト的に使用します。
040 *
041 * @og.formSample
042 * ●形式:
043 *  <og:databaseMetaData
044 *      dbid            = "{@DBID}"
045 *      catalog         = "{@catalog}"
046 *      schema          = "{@schema}"
047 *      tableName       = "{@tableName}"
048 *      columnName      = "{@columnName}"
049 *      typeName        = "{@typeName}"
050 *      attributeName   = "{@attriName}"
051 *      procedureName   = "{@procName}"
052 *      maxRowCount     = "{@maxRowCount}"
053 *      likeKey         = "{@likeKey}"
054 *  />
055 *
056 * ●body:なし
057 *
058 * ●Tag定義:
059 *   <og:databaseMetaData
060 *       dbid               【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します(初期値:null)
061 *       catalog            【TAG】(通常は使いません)Queryオブジェクトを作成する時のカタログを指定します
062 *       schema             【TAG】(通常は使いません)Queryオブジェクトを作成する時のスキーマを指定します
063 *       attributeName      【TAG】(通常は使いません)Queryオブジェクトを作成する時の属性名を指定します
064 *       columnName         【TAG】(通常は使いません)Queryオブジェクトを作成する時のカラム名を指定します
065 *       procedureName      【TAG】(通常は使いません)Queryオブジェクトを作成する時のプロダクト名を指定します
066 *       tableName          【TAG】(通常は使いません)Queryオブジェクトを作成する時のテーブル名を指定します
067 *       typeName           【TAG】(通常は使いません)Queryオブジェクトを作成する時のタイプ名を指定します
068 *       maxRowCount        【TAG】maxRowCount ResultSetで検索するパラメータの最大検索件数を指定します(初期値:20)
069 *       likeKey            【TAG】実行するメソッドを選別するための部分一致するキーを指定します
070 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
071 *   />
072 *
073 * ●使用例
074 *       <og:databaseMetaData />
075 *
076 * @og.group DB検索
077 *
078 * @version  0.9.0      2000/10/17
079 * @author       Kazuhiko Hasegawa
080 * @since    JDK5.0,
081 */
082public class DatabaseMetaDataTag extends CommonTagSupport {
083        /** このプログラムのVERSION文字列を設定します。   {@value} */
084        private static final String VERSION = "6.4.2.1 (2016/02/05)" ;
085        private static final long serialVersionUID = 642120160205L ;
086
087        private static final String getTimeDateFunctions= "このデータベースで使用可能な時間関数と日付関数をコンマで区切ったリストを取得します。" ;
088        private static final String supportsConvertFunc = "このデータベースによって、SQL の型間の CONVERT 関数がサポートされるかどうかを取得します。" ;
089        private static final String getAttributes               = "指定されたスキーマおよびカタログで使用可能なユーザ定義の型 (UDT) のための指定された型の指定された属性に関する記述を取得します。  " ;
090        private static final String getColumns                  = "指定されたカタログで使用可能なテーブル列の記述を取得します。  " ;
091        private static final String getIndexInfo                = "指定されたテーブルのインデックスと統計情報に関する記述を取得します。" ;
092        private static final String getSuperTables              = "このデータベースの特定のスキーマで定義されているテーブル階層の説明を取得します。  " ;
093        private static final String getSuperTypes               = "このデータベースの特定のスキーマで定義されているユーザ定義型 (UDT) 階層の説明を取得します。" ;
094        private static final String getTypeInfo                 = "このデータベースでサポートされているすべての標準 SQL の型に関する記述を取得します。" ;
095
096        private static final MetaDataInvoke[] METHOD_LIST = new MetaDataInvoke[] {
097                  new MetaDataInvoke( "getCatalogSeparator"             ,0,-1,   "このデータベースがカタログ名とテーブル名のセパレータとして使用する String" )
098                , new MetaDataInvoke( "getCatalogTerm"                          ,0,-1,   "「catalog」に対するデータベースベンダーの推奨用語を取得します。" )
099                , new MetaDataInvoke( "getDatabaseProductName"          ,0,-1,   "このデータベース製品の名前を取得します。" )
100                , new MetaDataInvoke( "getDatabaseProductVersion"       ,0,-1,   "このデータベース製品のバージョンを取得します。" )
101                , new MetaDataInvoke( "getDriverMajorVersion"           ,0,-1,   "この JDBC ドライバのメジャーバージョンを取得します。" )
102                , new MetaDataInvoke( "getDriverMinorVersion"           ,0,-1,   "この JDBC ドライバのマイナーバージョンを取得します。" )
103                , new MetaDataInvoke( "getDriverName"                           ,0,-1,   "この JDBC ドライバの名前を取得します。" )
104                , new MetaDataInvoke( "getDriverVersion"                        ,0,-1,   "この JDBC ドライバのバージョンを String" )
105                , new MetaDataInvoke( "getExtraNameCharacters"          ,0,-1,   "引用符で囲まれていない識別名に使用できるすべての「特殊」文字 (a-z,A-Z,0-9,および _ 以外) を取得します。" )
106                , new MetaDataInvoke( "getIdentifierQuoteString"        ,0,-1,   "SQL 識別子を引用するのに使用する文字列を取得します。" )
107                , new MetaDataInvoke( "getNumericFunctions"             ,0,-1,   "このデータベースで使用可能なコンマで区切った数学関数のリストを取得します。" )
108                , new MetaDataInvoke( "getProcedureTerm"                        ,0,-1,   "「procedure」に対するデータベースベンダーの推奨用語を取得します。" )
109                , new MetaDataInvoke( "getSchemaTerm"                           ,0,-1,   "「schema」に対するデータベースベンダーの推奨用語を取得します。" )
110                , new MetaDataInvoke( "getSearchStringEscape"           ,0,-1,   "ワイルドカード文字をエスケープするのに使用できる文字列を取得します。" )
111                , new MetaDataInvoke( "getSQLKeywords"                          ,0,-1,   "このデータベースの SQL キーワードであって、SQL92 のキーワードではない、すべてのキーワードをコンマで区切ったリストを取得します。" )
112                , new MetaDataInvoke( "getStringFunctions"                      ,0,-1,   "このデータベースで使用可能なコンマで区切った文字列関数のリストを取得します。" )
113                , new MetaDataInvoke( "getSystemFunctions"                      ,0,-1,   "このデータベースで使用可能なコンマで区切ったシステム関数のリストを取得します。" )
114                , new MetaDataInvoke( "getTimeDateFunctions"            ,0,-1,   "このデータベースで使用可能な時間関数と日付関数をコンマで区切ったリストを取得します。" )
115                , new MetaDataInvoke( "getURL"                                          ,0,-1,   "この DBMS の URL を取得します。" )
116                , new MetaDataInvoke( "getUserName"                             ,0,-1,   "このデータベースに記録されているユーザ名を取得します。" )
117
118                , new MetaDataInvoke( "getDefaultTransactionIsolation"  ,0,-1,   "このデータベースのデフォルトのトランザクション遮断レベルを取得します。" )
119                , new MetaDataInvoke( "getSQLStateType"                                 ,0,-1,   "Throwable.getSQLState によって返される SQLSTATE が X/Open (現在は Open Group) の SQL CLI であるか SQL99 であるかを示します。" )
120                , new MetaDataInvoke( "getResultSetHoldability"         ,0,-1,   "この ResultSet オブジェクトのデフォルトの保持機能を取得します。" )
121                , new MetaDataInvoke( "allProceduresAreCallable"        ,0,-1,   "getProcedures メソッドによって返されるすべてのプロシージャが、現在のユーザから呼び出せるかどうかを取得します。" )
122                , new MetaDataInvoke( "allTablesAreSelectable"          ,0,-1,   "getTables メソッドによって返されるすべてのテーブルが、現在のユーザによって使用できるかどうかを取得します。" )
123                , new MetaDataInvoke( "dataDefinitionCausesTransactionCommit",0,-1,     "トランザクションのデータ定義文が、トランザクションを強制的にコミットさせるかどうかを取得します。" )
124                , new MetaDataInvoke( "dataDefinitionIgnoredInTransactions"  ,0,-1,     "このデータベースによって、トランザクションでデータ定義文が無視されるかどうかを取得します。" )
125                , new MetaDataInvoke( "deletesAreDetected"                      ,1,-1,   "ResultSet.rowDeleted メソッドを呼び出すことによって可視の行が削除されたことを検出できるかどうかを取得します。" )
126                , new MetaDataInvoke( "doesMaxRowSizeIncludeBlobs"      ,0,-1,   "getMaxRowSize メソッドの戻り値が SQL データの型の LONGVARCHAR および LONGVARBINARY を含むかどうかを取得します。" )
127                , new MetaDataInvoke( "insertsAreDetected"                      ,1,-1,   "ResultSet.rowInserted メソッドを呼び出すことによって可視の行が挿入されたことを検出できるかどうかを取得します。" )
128                , new MetaDataInvoke( "isCatalogAtStart"                        ,0,-1,   "完全修飾されたテーブル名の開始部分 (または終了部分) にカタログが現れるかどうかを取得します。" )
129                , new MetaDataInvoke( "isReadOnly"                                      ,0,-1,   "このデータベースが読み込み専用モードかどうかを取得します。" )
130                , new MetaDataInvoke( "locatorsUpdateCopy"                      ,0,-1,   "LOB への変更が、コピーに対して行われたのか、LOB に直接行われたのかを示します。" )
131                , new MetaDataInvoke( "nullPlusNonNullIsNull"           ,0,-1,   "このデータベースが、NULL 値と非 NULL 値の連結を NULL とするかどうかを取得します。" )
132                , new MetaDataInvoke( "nullsAreSortedAtEnd"             ,0,-1,   "NULL 値が、終了時にソート順にかかわらずソートされるかどうかを取得します。" )
133                , new MetaDataInvoke( "nullsAreSortedAtStart"           ,0,-1,   "NULL 値が、開始時にソート順にかかわらずソートされるかどうかを取得します。" )
134                , new MetaDataInvoke( "nullsAreSortedHigh"                      ,0,-1,   "NULL 値が高位にソートされるかどうかを取得します。" )
135                , new MetaDataInvoke( "nullsAreSortedLow"                       ,0,-1,   "NULL 値が下位にソートされるかどうかを取得します。" )
136                , new MetaDataInvoke( "othersDeletesAreVisible"         ,1,-1,   "他で行われた削除が可視かどうかを取得します。" )
137                , new MetaDataInvoke( "othersInsertsAreVisible"         ,1,-1,   "他で行われた挿入が可視かどうかを取得します。" )
138                , new MetaDataInvoke( "othersUpdatesAreVisible"         ,1,-1,   "他で行われた更新が可視かどうかを取得します。" )
139                , new MetaDataInvoke( "ownDeletesAreVisible"            ,1,-1,   "結果セット自身の削除が可視かどうかを取得します。" )
140                , new MetaDataInvoke( "ownInsertsAreVisible"            ,1,-1,   "結果セット自身の挿入が可視かどうかを取得します。" )
141                , new MetaDataInvoke( "ownUpdatesAreVisible"            ,1,-1,   "指定された ResultSet オブジェクトについて、結果セット自身の更新が可視かどうかを取得します。" )
142                , new MetaDataInvoke( "storesLowerCaseIdentifiers"      ,0,-1,   "このデータベースが、大文字小文字が混在する引用符なしの SQL 識別子を、大文字小文字を区別しないで処理し、小文字で格納するかどうかを取得します。" )
143                , new MetaDataInvoke( "storesLowerCaseQuotedIdentifiers",0,-1,  "このデータベースが、大文字小文字が混在する引用符付きの SQL 識別子を、大文字小文字を区別しないで処理し、小文字で格納するかどうかを取得します。" )
144                , new MetaDataInvoke( "storesMixedCaseIdentifiers"              ,0,-1,  "このデータベースが、大文字小文字が混在する引用符なしの SQL 識別子を、大文字小文字を区別しないで処理し、大文字小文字混在で格納するかどうかを取得します。" )
145                , new MetaDataInvoke( "storesMixedCaseQuotedIdentifiers",0,-1,  "このデータベースが、大文字小文字が混在する引用符付きの SQL 識別子を、大文字小文字を区別しないで処理し、大文字小文字混在で格納するかどうかを取得します。" )
146                , new MetaDataInvoke( "storesUpperCaseIdentifiers"              ,0,-1,  "このデータベースが、大文字小文字が混在する引用符なしの SQL 識別子を、大文字小文字を区別しないで処理し、大文字で格納するかどうかを取得します。" )
147                , new MetaDataInvoke( "storesUpperCaseQuotedIdentifiers",0,-1,  "このデータベースが、大文字小文字が混在する引用符付きの SQL 識別子を、大文字小文字を区別しないで処理し、大文字で格納するかどうかを取得します。" )
148                , new MetaDataInvoke( "supportsAlterTableWithAddColumn" ,0,-1,  "このデータベースによって、追加列のある ALTER TABLE がサポートされるかどうかを取得します。" )
149                , new MetaDataInvoke( "supportsAlterTableWithDropColumn",0,-1,  "このデータベースによって、ドロップ列のある ALTER TABLE がサポートされるかどうかを取得します。" )
150                , new MetaDataInvoke( "supportsANSI92EntryLevelSQL"     ,0,-1,  "このデータベースによって、ANSI92 エントリレベルの SQL 文法がサポートされるかどうかを取得します。" )
151                , new MetaDataInvoke( "supportsANSI92FullSQL"                   ,0,-1,  "このデータベースによって、ANSI92 完全レベルの SQL 文法がサポートされるかどうかを取得します。" )
152                , new MetaDataInvoke( "supportsANSI92IntermediateSQL"   ,0,-1,  "このデータベースによって、ANSI92 中間レベルの SQL 文法がサポートされるかどうかを取得します。" )
153                , new MetaDataInvoke( "supportsBatchUpdates"                    ,0,-1,  "このデータベースによってバッチ更新がサポートされるかどうかを取得します。" )
154                , new MetaDataInvoke( "supportsCatalogsInDataManipulation"              ,0,-1,   "データ操作文でカタログ名を使用できるかどうかを取得します。" )
155                , new MetaDataInvoke( "supportsCatalogsInIndexDefinitions"              ,0,-1,   "インデックス定義文でカタログ名を使用できるかどうかを取得します。" )
156                , new MetaDataInvoke( "supportsCatalogsInPrivilegeDefinitions"  ,0,-1,  "特権定義文でカタログ名を使用できるかどうかを取得します。" )
157                , new MetaDataInvoke( "supportsCatalogsInProcedureCalls"        ,0,-1,  "プロシージャ呼び出し文でカタログ名を使用できるかどうかを取得します。" )
158                , new MetaDataInvoke( "supportsCatalogsInTableDefinitions"      ,0,-1,  "テーブル定義文でカタログ名を使用できるかどうかを取得します。" )
159                , new MetaDataInvoke( "supportsColumnAliasing"                          ,0,-1,  "このデータベースによって列の別名がサポートされるかどうかを取得します。  " )
160        //      , new MetaDataInvoke( "supportsConvertFunc"                             ,0,-1,  "このデータベースによって、SQL の型間の CONVERT 関数がサポートされるかどうかを取得します。" )
161                , new MetaDataInvoke( "supportsCoreSQLGrammar"                          ,0,-1,  "このデータベースによって、ODBC Core SQL 文法がサポートされるかどうかを取得します。" )
162                , new MetaDataInvoke( "supportsCorrelatedSubqueries"            ,0,-1,  "このデータベースによって照合関係サブクエリーがサポートされるかどうかを取得します。" )
163                , new MetaDataInvoke( "supportsDataDefinitionAndDataManipulationTransactions"   ,0,-1,  "このデータベースによって、トランザクションで、データ定義文とデータ操作文の両方がサポートされるかどうかを取得します。" )
164                , new MetaDataInvoke( "supportsDataManipulationTransactionsOnly",0,-1,  "このデータベースによって、トランザクションでデータ操作文だけがサポートされるかどうかを取得します。" )
165                , new MetaDataInvoke( "supportsDifferentTableCorrelationNames"  ,0,-1,  "テーブル相互関係名がサポートされる場合、テーブルの名前と異なる名前であるという制限を付けるかどうかを取得します。" )
166                , new MetaDataInvoke( "supportsExpressionsInOrderBy"            ,0,-1,  "このデータベースによって、ORDER BY リスト中で式がサポートされるかどうかを取得します。" )
167                , new MetaDataInvoke( "supportsExtendedSQLGrammar"                      ,0,-1,  "このデータベースによって、ODBC Extended SQL 文法がサポートされるかどうかを取得します。" )
168                , new MetaDataInvoke( "supportsFullOuterJoins"                          ,0,-1,  "このデータベースによって、完全入れ子の外部結合がサポートされるかどうかを取得します。" )
169                , new MetaDataInvoke( "supportsGetGeneratedKeys"                        ,0,-1,  "文が実行されたあとに自動生成キーを取得できるかどうかを取得します。" )
170                , new MetaDataInvoke( "supportsGroupBy"                                         ,0,-1,  "このデータベースによって、GROUP BY 節のフォームがサポートされるかどうかを取得します。" )
171                , new MetaDataInvoke( "supportsGroupByBeyondSelect"             ,0,-1,  "SELECT 文中のすべての列が GROUP BY 節に含まれるという条件で、このデータベースによって、GROUP BY 節で SELECT 文中にない列の使用がサポートされるかどうかを取得します。" )
172                , new MetaDataInvoke( "supportsGroupByUnrelated"                        ,0,-1,  "このデータベースによって、GROUP BY 節で SELECT 文中にない列の使用がサポートされるかどうかを取得します。" )
173                , new MetaDataInvoke( "supportsIntegrityEnhancementFacility",0,-1,      "このデータベースによって、SQL Integrity Enhancement Facility がサポートされるかどうかを取得します。" )
174                , new MetaDataInvoke( "supportsLikeEscapeClause"                        ,0,-1,  "このデータベースによって、LIKE エスケープ節の指定がサポートされるかどうかを取得します。" )
175                , new MetaDataInvoke( "supportsLimitedOuterJoins"                       ,0,-1,  "このデータベースによって、外部結合に関し、制限されたサポートが提供されるかどうかを取得します (supportsFullOuterJoins メソッドが true を返す場合は true)。" )
176                , new MetaDataInvoke( "supportsMinimumSQLGrammar"                       ,0,-1,  "このデータベースによって、ODBC Minimum SQL 文法がサポートされるかどうかを取得します。" )
177                , new MetaDataInvoke( "supportsMixedCaseIdentifiers"            ,0,-1,  "このデータベースが、大文字小文字が混在する引用符なしの SQL 識別子を、大文字小文字を区別して処理し、大文字小文字混在で格納するかどうかを取得します。" )
178                , new MetaDataInvoke( "supportsMixedCaseQuotedIdentifiers"      ,0,-1,  "このデータベースが、大文字小文字が混在する引用符付きの SQL 識別子を、大文字小文字を区別して処理し、結果として大文字小文字混在で格納するかどうかを取得します。" )
179                , new MetaDataInvoke( "supportsMultipleOpenResults"             ,0,-1,  "CallableStatement オブジェクトから同時に返された複数の ResultSet オブジェクトを持つことが可能かどうかを取得します。" )
180                , new MetaDataInvoke( "supportsMultipleResultSets"                      ,0,-1,  "このデータベースによって、execute メソッドの単一の呼び出しからの複数の ResultSet オブジェクトの取得がサポートされるかどうかを取得します。" )
181                , new MetaDataInvoke( "supportsMultipleTransactions"            ,0,-1,  "このデータベースが一度に複数のトランザクションを (異なった接続で) オープンできるかどうかを取得します。" )
182                , new MetaDataInvoke( "supportsNamedParameters"                         ,0,-1,  "このデータベースによって、callable 文への名前付きパラメータがサポートされるかどうかを取得します。" )
183                , new MetaDataInvoke( "supportsNonNullableColumns"                      ,0,-1,  "このデータベースの列を非 null として定義できるかどうかを取得します。" )
184                , new MetaDataInvoke( "supportsOpenCursorsAcrossCommit"         ,0,-1,  "このデータベースによって、コミット間でカーソルがオープンされたままの状態がサポートされるかどうかを取得します。" )
185                , new MetaDataInvoke( "supportsOpenCursorsAcrossRollback"       ,0,-1,  "このデータベースによって、ロールバック間でカーソルがオープンされたままの状態がサポートされるかどうかを取得します。" )
186                , new MetaDataInvoke( "supportsOpenStatementsAcrossCommit"      ,0,-1,  "このデータベースによって、コミット間で文がオープンされたままの状態がサポートされるかどうかを取得します。" )
187                , new MetaDataInvoke( "supportsOpenStatementsAcrossRollback",0,-1,      "このデータベースによって、ロールバック間で文がオープンされたままの状態がサポートされるかどうかを取得します。" )
188                , new MetaDataInvoke( "supportsOrderByUnrelated"                        ,0,-1,  "このデータベースによって、ORDER BY 節で SELECT 文中にない列の使用がサポートされるかどうかを取得します。" )
189                , new MetaDataInvoke( "supportsOuterJoins"                                      ,0,-1,  "このデータベースによって、外部結合のなんらかの形式がサポートされるかどうかを取得します。" )
190                , new MetaDataInvoke( "supportsPositionedDelete"                        ,0,-1,  "このデータベースによって、位置指定された DELETE 文がサポートされるかどうかを取得します。" )
191                , new MetaDataInvoke( "supportsPositionedUpdate"                        ,0,-1,  "このデータベースによって、位置指定された UPDATE 文がサポートされるかどうかを取得します。" )
192                , new MetaDataInvoke( "supportsResultSetConcurrency"            ,2,-1,  "このデータベースが、指定された結果セットの型と与えられた並行処理の種類の組み合わせをサポートするかどうかを取得します。" )
193                , new MetaDataInvoke( "supportsResultSetHoldability"            ,3,-1,  "このデータベースが、指定された結果セットの保持機能をサポートするかどうかを取得します。" )
194                , new MetaDataInvoke( "supportsResultSetType"                           ,4,ResultSet.TYPE_FORWARD_ONLY          ,       "このデータベースが、[TYPE_FORWARD_ONLY]指定された結果セットの型をサポートするかどうかを取得します。" )
195                , new MetaDataInvoke( "supportsResultSetType"                           ,4,ResultSet.TYPE_SCROLL_INSENSITIVE,   "このデータベースが、[TYPE_SCROLL_INSENSITIVE]指定された結果セットの型をサポートするかどうかを取得します。" )
196                , new MetaDataInvoke( "supportsResultSetType"                           ,4,ResultSet.TYPE_SCROLL_SENSITIVE      ,       "このデータベースが、[TYPE_SCROLL_SENSITIVE]指定された結果セットの型をサポートするかどうかを取得します。" )
197                , new MetaDataInvoke( "supportsSavepoints"                                      ,0,-1,  "このデータベースによってセーブポイントがサポートされるかどうかを取得します。" )
198                , new MetaDataInvoke( "supportsSchemasInDataManipulation"       ,0,-1,  "データ操作文でスキーマ名を使用できるかどうかを取得します。" )
199                , new MetaDataInvoke( "supportsSchemasInIndexDefinitions"       ,0,-1,  "インデックス定義文でスキーマ名を使用できるかどうかを取得します。" )
200                , new MetaDataInvoke( "supportsSchemasInPrivilegeDefinitions",0,-1,     "特権定義文でスキーマ名を使用できるかどうかを取得します。" )
201                , new MetaDataInvoke( "supportsSchemasInProcedureCalls"         ,0,-1,  "プロシージャ呼び出し文でスキーマ名を使用できるかどうかを取得します。" )
202                , new MetaDataInvoke( "supportsSchemasInTableDefinitions"       ,0,-1,  "テーブル定義文でスキーマ名を使用できるかどうかを取得します。" )
203                , new MetaDataInvoke( "supportsSelectForUpdate"                         ,0,-1,  "このデータベースによって SELECT FOR UPDATE 文がサポートされるかどうかを取得します。" )
204                , new MetaDataInvoke( "supportsStatementPooling"                        ,0,-1,  "このデータベースによって文のプールがサポートされるかどうかを取得します。" )
205                , new MetaDataInvoke( "supportsStoredProcedures"                        ,0,-1,  "このデータベースによって、ストアドプロシージャエスケープ構文を使用するストアドプロシージャコールがサポートされるかどうかを判定します。" )
206                , new MetaDataInvoke( "supportsSubqueriesInComparisons"         ,0,-1,  "このデータベースによって、比較式中でサブクエリーがサポートされるかどうかを取得します。" )
207                , new MetaDataInvoke( "supportsSubqueriesInExists"                      ,0,-1,  "このデータベースによって、EXISTS 式中でサブクエリーがサポートされるかどうかを取得します。" )
208                , new MetaDataInvoke( "supportsSubqueriesInIns"                         ,0,-1,  "このデータベースによって、IN 文中でサブクエリーがサポートされるかどうかを取得します。" )
209                , new MetaDataInvoke( "supportsSubqueriesInQuantifieds"         ,0,-1,  "このデータベースによって、定量化された式中でサブクエリーがサポートされるかどうかを取得します。" )
210                , new MetaDataInvoke( "supportsTableCorrelationNames"           ,0,-1,  "このデータベースによってテーブル相互関係名がサポートされるかどうかを取得します。" )
211                , new MetaDataInvoke( "supportsTransactionIsolationLevel"       ,4,Connection.TRANSACTION_READ_COMMITTED        ,       "このデータベースが、指定されたトランザクション遮断レベルをサポートするかどうかを取得します。" )
212                , new MetaDataInvoke( "supportsTransactionIsolationLevel"       ,4,Connection.TRANSACTION_READ_UNCOMMITTED      ,       "このデータベースが、指定されたトランザクション遮断レベルをサポートするかどうかを取得します。" )
213                , new MetaDataInvoke( "supportsTransactionIsolationLevel"       ,4,Connection.TRANSACTION_REPEATABLE_READ       ,       "このデータベースが、指定されたトランザクション遮断レベルをサポートするかどうかを取得します。" )
214                , new MetaDataInvoke( "supportsTransactionIsolationLevel"       ,4,Connection.TRANSACTION_SERIALIZABLE          ,       "このデータベースが、指定されたトランザクション遮断レベルをサポートするかどうかを取得します。" )
215                , new MetaDataInvoke( "supportsTransactions"    ,0,-1,  "このデータベースによってトランザクションがサポートされるかどうかを取得します。" )
216                , new MetaDataInvoke( "supportsUnion"                   ,0,-1,  "このデータベースによって SQL UNION がサポートされるかどうかを取得します。" )
217                , new MetaDataInvoke( "supportsUnionAll"                ,0,-1,  "このデータベースによって SQL UNION ALL がサポートされるかどうかを取得します。" )
218                , new MetaDataInvoke( "updatesAreDetected"              ,1,-1,  "ResultSet.rowUpdated メソッドを呼び出すことによって可視の行が更新されたことを検出できるかどうかを取得します。" )
219                , new MetaDataInvoke( "usesLocalFilePerTable"   ,0,-1,  "このデータベースが、各テーブルにファイルを使用するかどうかを取得します。" )
220                , new MetaDataInvoke( "usesLocalFiles"                  ,0,-1,  "このデータベースが、ローカルファイルにテーブルを格納するかどうかを取得します。" )
221                , new MetaDataInvoke( "getAttributes"                   ,72,-1, "指定されたスキーマおよびカタログで使用可能なユーザ定義の型 (UDT) のための指定された型の指定された属性に関する記述を取得します。  " )
222                , new MetaDataInvoke( "getBestRowIdentifier"    ,64,-1, "行を一意に識別するテーブルの最適な列セットに関する記述を取得します。" )
223                , new MetaDataInvoke( "getCatalogs"                     ,50,-1, "このデータベースで使用可能なカタログ名を取得します。" )
224                , new MetaDataInvoke( "getColumnPrivileges"     ,61,-1, "テーブルの列へのアクセス権に関する記述を取得します。  " )
225                , new MetaDataInvoke( "getColumns"                              ,61,-1, "指定されたカタログで使用可能なテーブル列の記述を取得します。  " )
226                , new MetaDataInvoke( "getCrossReference"               ,65,-1, "指定された主キーテーブルの主キー列を参照する指定された外部のキーテーブル中の、外部のキー列に関する記述 (テーブルが別のキーをインポートする方法を記述) を取得します。" )
227                , new MetaDataInvoke( "getExportedKeys"                 ,60,-1, "指定されたテーブルの主キー列 (テーブルによってエクスポートされた外部キー) を参照する外部キー列に関する記述を取得します。" )
228                , new MetaDataInvoke( "getImportedKeys"                 ,60,-1, "テーブルの外部キー列 (テーブルによってインポートされる主キー) を参照する主キー列に関する記述を取得します。" )
229                , new MetaDataInvoke( "getIndexInfo"                    ,63,-1, "指定されたテーブルのインデックスと統計情報に関する記述を取得します。" )
230                , new MetaDataInvoke( "getPrimaryKeys"                  ,60,-1, "指定されたテーブルの主キー列の記述を取得します。" )
231                , new MetaDataInvoke( "getProcedureColumns"     ,81,-1, "指定されたカタログのストアドプロシージャパラメータと結果列に関する記述を取得します。  " )
232                , new MetaDataInvoke( "getProcedures"                   ,80,-1, "指定されたカタログで使用可能なストアドプロシージャに関する記述を取得します。  " )
233                , new MetaDataInvoke( "getSchemas"                              ,50,-1, "このデータベースで使用可能なスキーマ名を取得します。" )
234                , new MetaDataInvoke( "getSuperTables"                  ,60,-1, "このデータベースの特定のスキーマで定義されているテーブル階層の説明を取得します。  " )
235                , new MetaDataInvoke( "getSuperTypes"                   ,70,-1, "このデータベースの特定のスキーマで定義されているユーザ定義型 (UDT) 階層の説明を取得します。" )
236                , new MetaDataInvoke( "getTablePrivileges"              ,60,-1, "カタログで使用可能な各テーブルに対するアクセス権に関する記述を取得します。" )
237                , new MetaDataInvoke( "getTables"                               ,62,-1, "指定されたカタログで使用可能なテーブルに関する記述を取得します。" )
238                , new MetaDataInvoke( "getTableTypes"                   ,50,-1, "このデータベースで使用可能なテーブルの型を取得します。" )
239                , new MetaDataInvoke( "getTypeInfo"                     ,50,-1, "このデータベースでサポートされているすべての標準 SQL の型に関する記述を取得します。" )
240                , new MetaDataInvoke( "getUDTs"                                 ,71,-1, "特定のスキーマで定義されているユーザ定義型 (UDT) の説明を取得します。" )
241                , new MetaDataInvoke( "getVersionColumns"               ,60,-1, "行の任意の値が変更された場合に、自動的に更新されるテーブルの列に関する記述を取得します。" )
242
243        // 5.5.3.2 (2012/06/08) JDk1.6 用のメソッドを追加します。
244                , new MetaDataInvoke( "autoCommitFailureClosesAllResultSets"    ,0,-1,  "autoCommit が true の場合に、ResultSet が保持可能であっても、すべてのオープンされた ResultSet がクローズされたことを SQLException が示すかどうかを取得します。" )
245                , new MetaDataInvoke( "supportsConvert"                                                 ,0,-1,  "このデータベースによって、JDBC 型 fromType と toType の間の変換に使用される JDBC スカラー関数 CONVERT がサポートされるかどうかを取得します。" )
246                , new MetaDataInvoke( "supportsStoredFunctionsUsingCallSyntax"  ,0,-1,  "このデータベースが、ストアドプロシージャーエスケープ構文を使用した、ユーザ定義関数またはベンダー関数の呼び出しをサポートするかどうかを取得します。" )
247                , new MetaDataInvoke( "getDatabaseMajorVersion"         ,0,-1,  "基本となるデータベースのメジャーバージョン番号を取得します。" )
248                , new MetaDataInvoke( "getDatabaseMinorVersion"         ,0,-1,  "基本となるデータベースのマイナーバージョン番号を取得します。" )
249                , new MetaDataInvoke( "getJDBCMajorVersion"             ,0,-1,  "このドライバの JDBC メジャーバージョン番号を取得します。" )
250                , new MetaDataInvoke( "getJDBCMinorVersion"             ,0,-1,  "このドライバの JDBC マイナーバージョン番号を取得します。" )
251                , new MetaDataInvoke( "getMaxBinaryLiteralLength"       ,0,-1,  "このデータベースで、インラインバイナリリテラル中に入れられる 16 進数の最大文字数を取得します。" )
252                , new MetaDataInvoke( "getMaxCatalogNameLength"         ,0,-1,  "このデータベースでの、カタログ名の最大文字数を取得します。" )
253                , new MetaDataInvoke( "getMaxCharLiteralLength"         ,0,-1,  "このデータベースでの、キャラクタリテラルの最大文字数を取得します。" )
254                , new MetaDataInvoke( "getMaxColumnNameLength"          ,0,-1,  "このデータベースでの、列名の最大文字数を取得します。" )
255                , new MetaDataInvoke( "getMaxColumnsInGroupBy"          ,0,-1,  "このデータベースでの、GROUP BY 節中の列数の最大値を取得します。" )
256                , new MetaDataInvoke( "getMaxColumnsInIndex"            ,0,-1,  "このデータベースでの、インデックス中の列数の最大値を取得します。" )
257                , new MetaDataInvoke( "getMaxColumnsInOrderBy"          ,0,-1,  "このデータベースでの、ORDER BY 節中の列数の最大値を取得します。" )
258                , new MetaDataInvoke( "getMaxColumnsInSelect"           ,0,-1,  "このデータベースでの、SELECT リスト中の列数の最大値を取得します。" )
259                , new MetaDataInvoke( "getMaxColumnsInTable"            ,0,-1,  "このデータベースでの、テーブル中の列数の最大値を取得します。" )
260                , new MetaDataInvoke( "getMaxConnections"                       ,0,-1,  "このデータベースに対して可能な並行接続の最大数を取得します。" )
261                , new MetaDataInvoke( "getMaxCursorNameLength"          ,0,-1,  "このデータベースでの、カーソル名の最大文字数を取得します。" )
262                , new MetaDataInvoke( "getMaxIndexLength"                       ,0,-1,  "このデータベースでの、インデックスの全部分を含む、インデックスの最大バイト数を取得します。" )
263                , new MetaDataInvoke( "getMaxProcedureNameLength"       ,0,-1,  "このデータベースでの、プロシージャー名の最大文字数を取得します。" )
264                , new MetaDataInvoke( "getMaxRowSize"                           ,0,-1,  "このデータベースでの、1 行の最大バイト数を取得します。" )
265                , new MetaDataInvoke( "getMaxSchemaNameLength"          ,0,-1,  "このデータベースでの、スキーマ名の最大文字数を取得します。" )
266                , new MetaDataInvoke( "getMaxStatementLength"           ,0,-1,  "このデータベースでの、SQL 文の最大文字数を取得します。" )
267                , new MetaDataInvoke( "getMaxStatements"                        ,0,-1,  "このデータベースの同時にオープンできるアクティブな文の最大数を取得します。" )
268                , new MetaDataInvoke( "getMaxTableNameLength"           ,0,-1,  "このデータベースでの、テーブル名の最大文字数を取得します。" )
269                , new MetaDataInvoke( "getMaxTablesInSelect"            ,0,-1,  "このデータベースでの、SELECT 文の最大テーブル数を取得します。" )
270                , new MetaDataInvoke( "getMaxUserNameLength"            ,0,-1,  "このデータベースでの、ユーザ名の最大文字数を取得します。" )
271
272                , new MetaDataInvoke( "getClientInfoProperties"         ,50,-1, "ドライバがサポートするクライアント情報プロパティーのリストを取得します。")
273                , new MetaDataInvoke( "getFunctionColumns"                      ,81,-1, "指定されたカタログのシステム関数またはユーザ関数のパラメータと返される型に関する記述を取得します。")
274                , new MetaDataInvoke( "getFunctions"                            ,80,-1, "指定されたカタログで使用可能なシステム関数およびユーザ関数に関する記述を取得します。")
275        } ;
276
277        // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
278        private String  dbid                    ;
279        private String  catalog                 ;
280        private String  schema                  ;
281        private String  tableName               ;
282        private String  columnName              ;
283        private String  typeName                ;
284        private String  attributeName   ;
285        private String  procedureName   ;
286        private int             rowNo                   ;
287        private int             maxRowCount             = 20;           // 5.5.3.2 (2012/06/08) 最大検索件数を、指定できるようにする。
288        private String  likeKey                 ;                       // 5.5.3.2 (2012/06/08) 特定の処理だけを実行できるように、あいまい検索
289
290        /**
291         * デフォルトコンストラクター
292         *
293         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
294         */
295        public DatabaseMetaDataTag() { super(); }               // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
296
297        /**
298         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
299         *
300         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
301         * @og.rev 4.0.0.1 (2007/12/03) try ~ catch ~ finally をきちんと行う。
302         *
303         * @return      後続処理の指示(EVAL_PAGE)
304         */
305        @Override
306        public int doEndTag() {
307                debugPrint();           // 4.0.0 (2005/02/28)
308                Connection conn = null;
309                boolean errFlag = true;
310                try {
311                        conn = ConnectionFactory.connection( dbid,getApplicationInfo() );       // 3.8.7.0 (2006/12/15)
312                        final DatabaseMetaData metaData = conn.getMetaData() ;
313
314                        callPrintMessage( metaData );
315                        errFlag = false;                // エラーではない
316                }
317                catch( final Throwable ex) {
318                        final String errMsg = "データベース処理を実行できませんでした。"
319                                                + ex.getMessage()  + CR ;
320
321                        throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
322                }
323                finally {
324                        // 以下のコーディングの見直しを考える必要有り。
325                        // Connection はプールしている為、close() しても再利用されるだけ。
326                        if( errFlag ) { ConnectionFactory.remove( conn,dbid ); }        // 削除
327                        else {                  ConnectionFactory.close( conn,dbid );  }        // 返却
328                }
329
330                jspPrint( "処理が完了しました。" + CR );          // 5.5.3.2 (2012/06/08) 終了メッセージ追加
331                return EVAL_PAGE ;
332        }
333
334        /**
335         * タグリブオブジェクトをリリースします。
336         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
337         *
338         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
339         * @og.rev 5.5.3.2 (2012/06/08) maxRowCount 最大検索件数を、指定できるようにする。
340         * @og.rev 5.5.3.2 (2012/06/08) likeKey 特定の処理だけを実行できるように、あいまい検索
341         */
342        @Override
343        protected void release2() {
344                super.release2();
345                dbid                    = null ;
346                catalog                 = null ;
347                schema                  = null ;
348                tableName               = null ;
349                columnName              = null ;
350                typeName                = null ;
351                procedureName   = null ;
352                attributeName   = null ;
353                rowNo                   = 0;
354                maxRowCount             = 20;           // 5.5.3.2 (2012/06/08) 最大検索件数を、指定できるようにする。
355                likeKey                 = null;         // 5.5.3.2 (2012/06/08) 特定の処理だけを実行できるように、あいまい検索
356        }
357
358        /**
359         * 画面にテーブルタグの(TR)として、情報を出力します。
360         *
361         * 第一引数が、String の場合のオーバーロードメソッドです。
362         *
363         * @param       arg1    第一引数(String)
364         * @param       lbl             ラベル
365         * @param       msg             メッセージ
366         */
367        private void printMessage( final String arg1, final String lbl, final String msg ) {
368                final String str = "<tr class=\"row_" + (rowNo++ % 2) + "\"><td>"
369                                 + rowNo + "</td><td>"                  // 5.5.3.2 (2012/06/08) 行番号を表示
370                                 + lbl + "</td><td>" + arg1 + "</td><td>" + msg + "</td></tr>" + CR ;
371                jspPrint( str );
372        }
373
374        /**
375         * 画面にテーブルとして、情報を出力します。
376         *
377         * 第一引数が、ResultSet の場合のオーバーロードメソッドです。
378         *
379         * @param       resultSet       ResultSetオブジェクト
380         * @param       msg                     メッセージ
381         */
382        private void printMessage( final ResultSet resultSet, final String msg ) {
383                final String str = msg + CR + makeTableTag( resultToString( resultSet ) ) ;
384                jspPrint( str );
385        }
386
387        /**
388         * 画面にテーブルとして、情報を出力します。
389         *
390         * 第一引数が、存在しない場合のオーバーロードメソッドです。
391         *
392         * @param       lbl     ラベル
393         * @param       msg     メッセージ
394         */
395        private void printMessage( final String lbl, final String msg ) {
396                final String str = msg + CR + "<table><tr><td>" + lbl + "</td></tr></table>" + CR ;
397                jspPrint( str );
398        }
399
400        /**
401         * 指定の文字列配列をテーブル上に表示する為の、テーブルを作成します。
402         *
403         * @og.rev 5.5.3.2 (2012/06/08) 行番号を表示するように修正
404         *
405         * @param       data    文字列配列の配列
406         *
407         * @return      文字列配列を表示する為のHTMLテーブル書式
408         * @og.rtnNotNull
409         */
410        private String makeTableTag( final String[][] data ) {
411                if( data == null || data.length == 0 ) { return "" ; }
412
413                final int maxRow = data.length ;
414                final int maxClm = data[0].length ;
415
416                final StringBuilder buf = new StringBuilder( BUFFER_LARGE )
417                        .append( "<table>" ).append( CR )
418                        .append( "<tr class=\"row_h\"><th>No</th>" );           // 5.5.3.2 (2012/06/08) 行番号を表示
419                for( int clm=0; clm<maxClm; clm++ ) {
420                        buf.append( "<th>" ).append( data[0][clm] ).append( "</th>" );
421                }
422                buf.append( "</tr>" ).append( CR );
423
424                for( int row=1; row<maxRow; row++ ) {
425                        buf.append( "<tr class=\"row_" ).append( (row-1) % 2 )
426                                .append( "\"><td>" ).append( row ).append( "</td>" );                   // 5.5.3.2 (2012/06/08) 行番号を表示
427                        for( int clm=0; clm<maxClm; clm++ ) {
428                                buf.append( "<td>" ).append( data[row][clm] ).append( "</td>" );
429                        }
430                        buf.append( "</tr>" ).append( CR );
431                }
432                buf.append( "</table>" ).append( CR );
433
434                return buf.toString();
435        }
436
437        /**
438         * ステートメントと引数により、Queryを実行します。
439         * これは、Prepared クエリーの検索のみ実行します。
440         * 結果は,すべて文字列に変換されて格納されます。
441         *
442         * @og.rev 5.5.3.2 (2012/06/08) 最大検索件数を、指定できるようにする。
443         * @og.rev 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
444         *
445         * @param   resultSet ResultSetオブジェクト
446         *
447         * @return  ResultSetの検索結果配列
448         * @og.rtnNotNull
449         */
450        private String[][] resultToString( final ResultSet resultSet ) {
451                final ArrayList<String[]> data = new ArrayList<>();
452                try {
453                        // 6.0.4.0 (2014/11/28) ResultSetValue を使用するように変更。
454                        final ResultSetValue rsv = new ResultSetValue( resultSet );
455
456                        data.add( rsv.getNames() );
457
458                        // とりあえず MAX 10件とする。
459                        int maxcnt = 0 ;
460                        // 5.5.3.2 (2012/06/08) 最大検索件数を、指定できるようにする。
461                        while( rsv.next() && maxcnt++ < maxRowCount ) {
462                                data.add( rsv.getValues() );
463                        }
464                }
465                catch( final SQLException ex) {
466                        final String errMsg = "処理結果を実行できませんでした。"
467                                                + ex.getMessage();              // 5.1.8.0 (2010/07/01) errMsg 修正
468                        throw new HybsSystemException( errMsg,ex );             // 3.5.5.4 (2004/04/15) 引数の並び順変更
469                }
470
471                final int size = data.size();
472                String[][] rtn = new String[size][];
473                for( int i=0; i<size; i++ ) {
474                        rtn[i] = data.get(i);
475                }
476
477                return rtn;
478        }
479
480        /**
481         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します(初期値:null)。
482         *
483         * @og.tag Queryオブジェクトを作成する時のDB接続IDを指定します。
484         *
485         * @param       id データベース接続ID
486         */
487        public void setDbid( final String id ) {
488                dbid = nval( getRequestParameter( id ),dbid );
489        }
490
491        /**
492         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のカタログを指定します(初期値:null)。
493         *
494         * @og.tag Queryオブジェクトを作成する時のカタログを指定します。
495         *
496         * @param       val     カタログ情報
497         */
498        public void setCatalog( final String val ) {
499                catalog = nval( getRequestParameter( val ),catalog );
500        }
501
502        /**
503         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のスキーマを指定します。
504         *
505         * @og.tag Queryオブジェクトを作成する時のスキーマを指定します。
506         *
507         * @param       val     スキーマ情報
508         */
509        public void setSchema( final String val ) {
510                schema = nval( getRequestParameter( val ),schema );
511        }
512
513        /**
514         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のテーブル名を指定します。
515         *
516         * @og.tag Queryオブジェクトを作成する時のテーブル名を指定します。
517         *
518         * @param       val     テーブル名情報
519         */
520        public void setTableName( final String val ) {
521                tableName = nval( getRequestParameter( val ),tableName );
522        }
523
524        /**
525         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のカラム名を指定します。
526         *
527         * @og.tag Queryオブジェクトを作成する時のカラム名を指定します。
528         *
529         * @param       val     カラム名情報
530         */
531        public void setColumnName( final String val ) {
532                columnName = nval( getRequestParameter( val ),columnName );
533        }
534
535        /**
536         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のタイプ名を指定します。
537         *
538         * @og.tag Queryオブジェクトを作成する時のタイプ名を指定します。
539         *
540         * @param       val     タイプ名情報
541         */
542        public void setTypeName( final String val ) {
543                typeName = nval( getRequestParameter( val ),typeName );
544        }
545
546        /**
547         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のプロダクト名を指定します。
548         *
549         * @og.tag Queryオブジェクトを作成する時のプロダクト名を指定します。
550         *
551         * @param       val     プロダクト名情報
552         */
553        public void setProcedureName( final String val ) {
554                procedureName = nval( getRequestParameter( val ),procedureName );
555        }
556
557        /**
558         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時の属性名を指定します。
559         *
560         * @og.tag Queryオブジェクトを作成する時の属性名を指定します。
561         *
562         * @param       val     属性名情報
563         */
564        public void setAttributeName( final String val ) {
565                attributeName = nval( getRequestParameter( val ),attributeName );
566        }
567
568        /**
569         * 【TAG】maxRowCount ResultSetで検索するパラメータの最大検索件数を指定します(初期値:20)。
570         *
571         * @og.tag
572         ResultSetで検索する最大検索件数を指定します
573         * 大量に検索されて、処理速度が低下するのを避けるため、最大件数を指定します。
574         * 他のタグの maxRowCount の初期値設定(初期値:DB_MAX_ROW_COUNT)は利用せず、独自に設定値を持っています。
575         * 0は、無制限とします。
576         *
577         * @og.rev 5.5.3.2 (2012/06/08) likeKey 特定の処理だけを実行できるように、あいまい検索
578         * @og.rev 5.5.8.5 (2012/11/27) 0を無制限として処理します。
579         *
580         * @param       maxSize 最大件数
581         */
582        public void setMaxRowCount( final String maxSize ) {
583                maxRowCount = nval( getRequestParameter( maxSize ),maxRowCount );
584                if( maxRowCount == 0 ) { maxRowCount = Integer.MAX_VALUE ; }                    // 5.5.8.5 (2012/11/27)
585        }
586
587        /**
588         * 【TAG】実行するメソッドを選別するための部分一致するキーを指定します。
589         *
590         * @og.tag
591         * DatabaseMetaData で取得できる各種情報をアクセスするにあたり、指定のキーで部分一致する
592         * メソッドだけ処理するように指定します。
593         * メソッドの部分一致で判断します。
594         * 処理は、大文字、小文字を認識したうえで、部分一致で判定します。
595         *
596         * @og.rev 5.5.3.2 (2012/06/08) likeKey 特定の処理だけを実行できるように、あいまい検索
597         *
598         * @param       key     実行するメソッドを選別するためのキー
599         */
600        public void setLikeKey( final String key ) {
601                likeKey = nval( getRequestParameter( key ),likeKey );
602        }
603
604        /**
605         * 各メソッド情報を画面に出力していきます。
606         *
607         * @og.rev 5.5.3.2 (2012/06/08) JDk1.6 用のメソッドを追加します。
608         * @og.rev 6.4.2.1 (2016/02/05) try-with-resources 文が使えないので、通常の try 文で、close する。
609         *
610         * @param metaData DatabaseMetaDataオブジェクト
611         * @throws Throwable 何らかのエラーが発生した場合。
612         */
613        private void callPrintMessage( final DatabaseMetaData metaData ) throws Throwable {
614                // 単体のリターン値を持つ メタデータ
615
616                final Integer type = ResultSet.TYPE_FORWARD_ONLY ;
617                final Integer concurrency = ResultSet.CONCUR_READ_ONLY;
618                final Integer holdability = ResultSet.CLOSE_CURSORS_AT_COMMIT;
619
620                jspPrint( "<table>" );
621                jspPrint( "<tr class=\"row_h\"><th>No</th><th>キー</th><th>値</th><th>説明</th></tr>" );
622
623                // 5.5.3.2 (2012/06/08) 個別に呼び出す箇所を、リフレクションに変更。
624                for( int i=0; i<METHOD_LIST.length; i++ ) {
625                        final MetaDataInvoke inv = METHOD_LIST[i];
626                        if( inv.isUseMethod( likeKey ) && inv.getType() < 10 ) {
627                                Object obj = null;
628                                boolean isFume = false;         // 6.0.2.5 (2014/10/31) default に break を追記する為に、ロジック修正
629                                switch( inv.getType() ) {
630                                        // 6.1.0.0 (2014/12/26) findBugs: Bug type DB_DUPLICATE_SWITCH_CLAUSES (click for details)
631                                        // switch 文の2つの case のために同じコードを使用しています。
632                                        case 0:
633                                        case 4: obj = inv.invokeA( metaData );                                  break;
634                                        case 1: obj = inv.invokeA( metaData,type );                             break;
635                                        case 2: obj = inv.invokeA( metaData,type,concurrency ); break;
636                                        case 3: obj = inv.invokeA( metaData,holdability );              break;
637                                        default : isFume = true;                                                                break;                          // 6.0.2.5 (2014/10/31)
638                                }
639                                if( isFume ) { jspPrint( "*** タイプ不明 ***" + BR ); continue; }    // 6.0.2.5 (2014/10/31)
640                                final String msg = (obj == null) ? inv.getErrMsg() : String.valueOf( obj );
641
642                                final String str = "<tr class=\"row_" + (rowNo++ % 2) + "\"><td>"
643                                                + rowNo + "</td><td>"                   // 5.5.3.2 (2012/06/08) 行番号を表示
644                                                + inv.getMethod() + "</td><td>" + msg + "</td><td>" + inv.getComment() + "</td></tr>" + CR ;
645                                jspPrint( str );
646                        }
647                }
648                try { printMessage( metaData.getTimeDateFunctions() ,"getTimeDateFunctions",getTimeDateFunctions ); }
649                        catch( final Throwable e ) { printMessage( e.getMessage(),"getTimeDateFunctions",getTimeDateFunctions ); }
650
651                jspPrint( "</table>" );
652
653                if( metaData.supportsConvert() ) {
654                        supportsConvert( metaData );
655                }
656
657                // 5.5.3.2 (2012/06/08) 個別に呼び出す箇所を、リフレクションに変更。
658                for( int i=0; i<METHOD_LIST.length; i++ ) {
659                        final MetaDataInvoke inv = METHOD_LIST[i];
660                        if( inv.isUseMethod( likeKey ) && inv.getType() >= 10 ) {
661                                ResultSet obj = null;
662                                // 6.4.2.1 (2016/02/05) try-with-resources 文が使えないので、通常の try 文で、close する。
663                                try {
664                                        boolean isFume = false;         // 6.0.2.5 (2014/10/31) default に break を追記する為に、ロジック修正
665                                        switch( inv.getType() ) {
666                                                case 50: obj = inv.invokeB( metaData ); break;
667                                                case 60:
668                                                case 62:
669                                                case 63:
670                                                case 64:
671                                                case 65: obj = inv.invokeB( metaData, catalog, schema, tableName ); break;
672                                                case 70:
673                                                case 71: obj = inv.invokeB( metaData, catalog, schema, typeName ); break;
674                                                case 61: obj = inv.invokeB( metaData, catalog, schema, tableName, columnName ); break;
675                                                case 72: obj = inv.invokeB( metaData, catalog, schema, typeName, attributeName ); break;
676                                                case 81: obj = inv.invokeB( metaData, catalog, schema, procedureName, columnName ); break;
677                                                case 80: obj = inv.invokeB( metaData, catalog, schema, procedureName ); break;
678                                                default : isFume = true; break;                                                                                         // 6.0.2.5 (2014/10/31)
679                                        }
680                                        if( isFume ) { jspPrint( "*** タイプ不明 ***" + BR ); continue; }    // 6.0.2.5 (2014/10/31)
681
682                                        jspPrint( inv.getMethod() + ":" + inv.getComment() + BR );
683                                        // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..;
684                                        if( obj == null ) {
685                                                jspPrint( inv.getErrMsg() + BR );
686                                        }
687                                        else {
688                                                jspPrint( makeTableTag( resultToString( obj ) ) );
689                                        }
690                                }
691                                finally {
692                                        Closer.resultClose( obj );
693                                }
694                        }
695                }
696
697                // 以下、リフレクションが、エラーなどで結果を返さないメソッド。
698                jspPrint( "****************************************************************************************************" + BR );
699
700                if( likeKey == null || "getAttributes".indexOf( likeKey ) >= 0 ) {
701                        jspPrint( "getAttributes:" + getAttributes + BR );
702                        try { printMessage( metaData.getAttributes(catalog, schema, typeName, attributeName) ,getAttributes); }
703                                catch( final Throwable e ) { printMessage( e.getMessage() ,getAttributes); }
704                }
705                if( likeKey == null || "getColumns".indexOf( likeKey ) >= 0 ) {
706                        jspPrint( "getColumns:" + getColumns + BR );
707                        try { printMessage( metaData.getColumns(catalog, schema, tableName, columnName) ,getColumns); }
708                                catch( final Throwable e ) { printMessage( e.getMessage() ,getColumns); }
709                }
710                if( likeKey == null || "getIndexInfo".indexOf( likeKey ) >= 0 ) {
711                        jspPrint( "getIndexInfo:" + getIndexInfo + BR );
712                        try { printMessage( metaData.getIndexInfo(catalog, schema, tableName, false, false) ,getIndexInfo); }
713                                catch( final Throwable e ) { printMessage( e.getMessage() ,getIndexInfo); }
714                }
715                if( likeKey == null || "getSuperTables".indexOf( likeKey ) >= 0 ) {
716                        jspPrint( "getSuperTables:" + getSuperTables + BR );
717                        try { printMessage( metaData.getSuperTables(catalog, schema, tableName) ,getSuperTables); }
718                                catch( final Throwable e ) { printMessage( e.getMessage() ,getSuperTables); }
719                }
720                if( likeKey == null || "getSuperTypes".indexOf( likeKey ) >= 0 ) {
721                        jspPrint( "getSuperTypes:" + getSuperTypes + BR );
722                        try { printMessage( metaData.getSuperTypes(catalog, schema, typeName) ,getSuperTypes); }
723                                catch( final Throwable e ) { printMessage( e.getMessage() ,getSuperTypes); }
724                }
725                if( likeKey == null || "getTypeInfo".indexOf( likeKey ) >= 0 ) {
726                        jspPrint( "getTypeInfo:" + getTypeInfo + BR );
727                        try { printMessage( metaData.getTypeInfo() ,getTypeInfo); }
728                                catch( final Throwable e ) { printMessage( e.getMessage() ,getTypeInfo); }
729                }
730        }
731
732        /**
733         * データベースの Types 定数を文字列に変換したテーブルを画面に出力します。
734         *
735         * @param metaData DatabaseMetaDataオブジェクト
736         * @throws Throwable 何らかのエラーが発生した場合。
737         * @see java.sql.Types
738         */
739        private void supportsConvert( final DatabaseMetaData metaData ) throws Throwable {
740
741                final int cnt = 36;
742                int[]    key = new int[cnt] ;
743                String[] msg = new String[cnt] ;
744
745                int i = 0;
746                key[i] = Types.ARRAY ;                  msg[i++] = "ARRAY" ;                    // 0
747                key[i] = Types.BIGINT ;                 msg[i++] = "BIGINT" ;                   // 1
748                key[i] = Types.BINARY ;                 msg[i++] = "BINARY" ;                   // 2
749                key[i] = Types.BIT ;                    msg[i++] = "BIT" ;                              // 3
750                key[i] = Types.BLOB ;                   msg[i++] = "BLOB" ;                             // 4
751                key[i] = Types.BOOLEAN ;                msg[i++] = "BOOLEAN" ;                  // 5
752                key[i] = Types.CHAR ;                   msg[i++] = "CHAR" ;                             // 6
753                key[i] = Types.CLOB ;                   msg[i++] = "CLOB" ;                             // 7
754                key[i] = Types.DATALINK ;               msg[i++] = "DATALINK" ;                 // 8
755                key[i] = Types.DATE ;                   msg[i++] = "DATE" ;                             // 9
756                key[i] = Types.DECIMAL ;                msg[i++] = "DECIMAL" ;                  // 10
757                key[i] = Types.DISTINCT ;               msg[i++] = "DISTINCT" ;                 // 11
758                key[i] = Types.DOUBLE ;                 msg[i++] = "DOUBLE" ;                   // 12
759                key[i] = Types.FLOAT ;                  msg[i++] = "FLOAT" ;                    // 13
760                key[i] = Types.INTEGER ;                msg[i++] = "INTEGER" ;                  // 14
761                key[i] = Types.JAVA_OBJECT ;    msg[i++] = "JAVA_OBJECT" ;              // 15
762                key[i] = Types.LONGNVARCHAR ;   msg[i++] = "LONGNVARCHAR" ;             // 16   5.5.3.2 (2012/06/08)
763                key[i] = Types.LONGVARBINARY ;  msg[i++] = "LONGVARBINARY" ;    // 17
764                key[i] = Types.LONGVARCHAR ;    msg[i++] = "LONGVARCHAR" ;              // 18
765                key[i] = Types.NCHAR ;                  msg[i++] = "NCHAR" ;                    // 19   5.5.3.2 (2012/06/08)
766                key[i] = Types.NCLOB ;                  msg[i++] = "NCLOB" ;                    // 20   5.5.3.2 (2012/06/08)
767                key[i] = Types.NULL ;                   msg[i++] = "NULL" ;                             // 21
768                key[i] = Types.NUMERIC ;                msg[i++] = "NUMERIC" ;                  // 22
769                key[i] = Types.NVARCHAR ;               msg[i++] = "NVARCHAR" ;                 // 23   5.5.3.2 (2012/06/08)
770                key[i] = Types.OTHER ;                  msg[i++] = "OTHER" ;                    // 24
771                key[i] = Types.REAL ;                   msg[i++] = "REAL" ;                             // 25
772                key[i] = Types.REF ;                    msg[i++] = "REF" ;                              // 26
773                key[i] = Types.ROWID ;                  msg[i++] = "ROWID" ;                    // 27   5.5.3.2 (2012/06/08)
774                key[i] = Types.SMALLINT ;               msg[i++] = "SMALLINT" ;                 // 28   5.5.3.2 (2012/06/08)
775                key[i] = Types.SQLXML ;                 msg[i++] = "SQLXML" ;                   // 29
776                key[i] = Types.STRUCT ;                 msg[i++] = "STRUCT" ;                   // 30
777                key[i] = Types.TIME ;                   msg[i++] = "TIME" ;                             // 31
778                key[i] = Types.TIMESTAMP ;              msg[i++] = "TIMESTAMP" ;                // 32
779                key[i] = Types.TINYINT ;                msg[i++] = "TINYINT" ;                  // 33
780                key[i] = Types.VARBINARY ;              msg[i++] = "VARBINARY" ;                // 34
781                key[i] = Types.VARCHAR ;                msg[i  ] = "VARCHAR" ;                  // 35
782
783                // それぞれ、Types 名称用のフィールドを追加
784                String[][] table = new String[cnt+1][cnt+1];            // ヘッダー行を追加
785                for( int hd=0; hd<cnt; hd++ ) {
786                        table[0][hd+1] = msg[hd];               // 行のヘッダー
787                        table[hd+1][0] = msg[hd];               // 列のヘッダー
788                }
789
790                for( int row=0; row<cnt; row++ ) {
791                        for( int clm=0; clm<cnt; clm++ ) {
792                                if( metaData.supportsConvert( key[row], key[clm]) ) {
793                                        table[row+1][clm+1] = "○" ;
794                                }
795                                else {
796                                        table[row+1][clm+1] = "×" ;
797                                }
798                        }
799                }
800
801                jspPrint( supportsConvertFunc + BR );
802                jspPrint( makeTableTag( table ) );
803        }
804
805        /**
806         * メソッド処理を行う内部クラス
807         */
808        private static final class MetaDataInvoke {
809                private static final int     scope    = 0;
810                private static final boolean nullable = true;
811
812                private final String  method  ;
813                private final int     type    ;                 // 0:引数なし 1: 2: 3: 4:内部value
814                private final Integer value   ;
815                private final String  comment ;
816
817                private String errMsg;
818
819                /**
820                 * メソッド処理を行うクラスのコンストラクター
821                 *
822                 * @param       method  メソッドの文字列表現
823                 * @param       type    呼出しタイプ
824                 * @param       value   設定値
825                 * @param       comment この処理に関するコメント
826                 */
827                public MetaDataInvoke( final String method,final int type,final int value,final String comment ) {
828                        this.method  = method  ;
829                        this.type        = type    ;
830                        this.value   = Integer.valueOf(value) ;
831                        this.comment = comment ;
832                }
833
834                /**
835                 * メソッドを返します。
836                 *
837                 * @return      メソッド
838                 */
839                public String getMethod() { return method; }
840
841                /**
842                 * LIKEキーをメソッドが含むかどうか。
843                 *
844                 * @param       likeKey LIKEキー
845                 * @return      LIKEキーが、null か、または、LIKEキーをメソッドが含む場合、true
846                 */
847                public boolean isUseMethod( final String likeKey ) {
848                        return likeKey == null || method.indexOf( likeKey ) >= 0 ;
849                }
850
851                /**
852                 * タイプを返します。
853                 *
854                 * @return      タイプ
855                 */
856                public int getType() { return type; }
857
858                /**
859                 * コメントを返します。
860                 *
861                 * @return      コメント
862                 */
863                public String getComment() { return comment; }
864
865                /**
866                 * エラーメッセージを返します。
867                 *
868                 * @return      エラーメッセージ
869                 */
870                public String getErrMsg() { return errMsg; }
871
872                /**
873                 * DatabaseMetaDataのオブジェクトを元に、動的にメソッド呼び出しを行います。
874                 * メタデータ情報の取出しに使用します。
875                 * 処理タイプに応じたメソッド呼び出しを行います。
876                 *
877                 * 0    引数なし
878                 * 1    (int)
879                 * 2    (int,int)
880                 * 3    (int)
881                 * 4    内部value
882                 *
883                 * @param       metaData        DatabaseMetaDataオブジェクト
884                 * @param       vals            引数の文字列配列(可変長引数)
885                 * @return      実行結果のオブジェクト
886                 */
887                public Object invokeA( final DatabaseMetaData metaData , final Integer... vals  ) {
888                        Object obj = null ;
889                        synchronized( metaData ) {
890                                try {
891                                        if( type == 0 ) {
892                                                obj = metaData.getClass().getMethod( method ).invoke(metaData);
893                                        } else if( type == 1 || type == 3 ) {
894                                                obj = metaData.getClass().getMethod( method,int.class )
895                                                                                                        .invoke(metaData,vals[0]);
896                                        } else if( type == 2 ) {
897                                                obj = metaData.getClass().getMethod( method,int.class,int.class )
898                                                                                                        .invoke(metaData,vals[0],vals[1]);
899                                        } else if( type == 4 ) {
900                                                obj = metaData.getClass().getMethod( method,int.class )
901                                                                                                        .invoke(metaData,value);
902                                        } else {
903                                                errMsg = "*** リフレクションタイプなしエラー ***";
904                                        }
905                                }
906                                catch( final Throwable ex ) {
907                                        errMsg = "*** 実行時エラー ***" + ex.getMessage();
908                                        obj = null;                             // "*** 実行時エラー ***"
909                                }
910                        }
911                        if( obj == null && errMsg == null ) { errMsg = "サポートされない機能です。"; }
912                        return obj ;
913                }
914
915                /**
916                 * DatabaseMetaDataのオブジェクトを元に、動的にメソッド呼び出しを行います。
917                 * メタデータ情報の取出しに使用します。
918                 * 処理タイプに応じたメソッド呼び出しを行います。
919                 *
920                 * 50   引数なし
921                 * 60   (catalog, schema, tableName)
922                 * 70   (catalog, schema, typeName)
923                 * 80   (catalog, schema, procedureName)
924                 * 62   (catalog, schema, tableName, (String[])null)     // String[]
925                 * 71   (catalog, schema, typeName, (int[])null)                 // int[]
926                 * 63   (catalog, schema, tableName, false, false)
927                 * 61   (catalog, schema, tableName, columnName)
928                 * 72   (catalog, schema, typeName, attributeName)
929                 * 81   (catalog, schema, procedureName, columnName)
930                 * 64   (catalog, schema, tableName, (int)scope, (boolean)nullable)
931                 * 65   (catalog, schema, tableName, (String)null, (String)null, (String)null)
932                 *
933                 * @param       metaData        DatabaseMetaDataオブジェクト
934                 * @param       vals            引数の文字列配列(可変長引数)
935                 * @return      ResultSetオブジェクト
936                 */
937                public ResultSet invokeB( final DatabaseMetaData metaData , final String... vals  ) {
938                        ResultSet obj = null ;
939                        synchronized( metaData ) {
940                                try {
941                                        if( type == 50 ) {      // 引数なし
942                                                obj = (ResultSet)metaData.getClass().getMethod( method ).invoke(metaData);
943                                        } else if( type == 60 || type == 70 || type == 80 ) {
944                                                obj = (ResultSet)metaData.getClass()
945                                                                .getMethod( method,String.class,String.class,String.class )
946                                                                .invoke(metaData,vals[0],vals[1],vals[2]);
947                                        } else if( type == 62 ) {
948                                                obj = (ResultSet)metaData.getClass()
949                                                                .getMethod( method,String.class,String.class,String.class,String[].class )
950                                                                .invoke(metaData,vals[0],vals[1],vals[2],null);
951                                        } else if( type == 71 ) {
952                                                obj = (ResultSet)metaData.getClass()
953                                                                .getMethod( method,String.class,String.class,String.class,int[].class )
954                                                                .invoke(metaData,vals[0],vals[1],vals[2],null);
955                                        } else if( type == 63 ) {
956                                                obj = (ResultSet)metaData.getClass()
957                                                                .getMethod( method,String.class,String.class,String.class,boolean.class,boolean.class )
958                                                                .invoke(metaData,vals[0],vals[1],vals[2],false,false);
959                                        } else if( type == 61 || type == 72 || type == 81 ) {
960                                                obj = (ResultSet)metaData.getClass()
961                                                                .getMethod( method,String.class,String.class,String.class,String.class )
962                                                                .invoke(metaData,vals[0],vals[1],vals[2],vals[3]);
963                                        } else if( type == 64 ) {
964                                                obj = (ResultSet)metaData.getClass()
965                                                                .getMethod( method,String.class,String.class,String.class,int.class,boolean.class )
966                                                                .invoke(metaData,vals[0],vals[1],vals[2],scope,nullable);
967                                        } else if( type == 65 ) {
968                                                obj = (ResultSet)metaData.getClass()
969                                                                .getMethod( method,String.class,String.class,String.class,String.class,String.class,String.class )
970                                                                .invoke(metaData,vals[0],vals[1],vals[2],null,null,null);
971                                        } else {
972                                                errMsg = "*** リフレクションタイプなしエラー ***";
973                                        }
974                                }
975                                catch( final Throwable ex ) {
976                                        errMsg = "*** 実行時エラー ***" + ex.getMessage();
977                                        obj = null;                             // "*** 実行時エラー ***"
978                                }
979                        }
980                        if( obj == null && errMsg == null ) { errMsg = "サポートされない機能です。"; }
981                        return obj ;
982                }
983        }
984
985        /**
986         * このオブジェクトの文字列表現を返します。
987         * 基本的にデバッグ目的に使用します。
988         *
989         * @return このクラスの文字列表現
990         * @og.rtnNotNull
991         */
992        @Override
993        public String toString() {
994                return ToString.title( this.getClass().getName() )
995                                .println( "VERSION"                     ,VERSION        )
996                                .println( "dbid"                        ,dbid           )
997                                .println( "catalog"                     ,catalog        )
998                                .println( "schema"                      ,schema         )
999                                .println( "tableName"           ,tableName      )
1000                                .println( "columnName"          ,columnName     )
1001                                .println( "typeName"            ,typeName       )
1002                                .println( "procedureName"       ,procedureName)
1003                                .println( "attributeName"       ,attributeName)
1004                                .println( "rowNo"                       ,rowNo          )
1005                                .println( "Other..."            ,getAttributes().getAttribute() )
1006                                .fixForm().toString() ;
1007        }
1008}