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