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     */
016    package org.opengion.fukurou.db;
017    
018    import java.io.File;
019    import java.net.URL;
020    import java.util.ArrayList;
021    import java.util.Arrays;
022    import java.util.Comparator;
023    import java.util.LinkedHashMap;
024    import java.util.List;
025    import java.util.Locale;
026    import java.util.Map;
027    
028    import org.opengion.fukurou.util.StringUtil;
029    import org.opengion.fukurou.util.FileUtil;
030    import org.opengion.fukurou.util.LogWriter;
031    import org.opengion.fukurou.xml.DomParser;
032    import org.w3c.dom.Document;
033    import org.w3c.dom.Element;
034    import org.w3c.dom.Node;
035    import org.w3c.dom.NodeList;
036    
037    /**
038     * DB設定XMLの?をJAXBを利用してロードす?
039     * Driverをロードす?
040     * 上記2つの機?を備えたクラスで?
041     *
042     * 外部からはgetDbidメソ?を利用してDB設?ExpandedDbid?を取得します?
043     * DB設定情報が無??合にXMLを読みに?ます?
044     * こ?DBIDを決めるキーは、?部取り込み字に、大?変換されます?で、大??
045     * 小文字?区別はありません?
046     *
047     * @og.rev 4.0.0.0 (2007/10/25) 新規作?
048     * @og.rev 5.1.7.0 (2010/06/01) org.opengion.fukurou.xml.jaxb.dbid 関??
049     * @og.group 初期?
050     *
051     * @version  4.0
052     * @author 高橋正?
053     * @since   JDK6.0,
054     */
055    public class DatabaseConfig {
056    
057            // fukurou?完結させるため、HybsDataからは読み込まずにここに書?
058            private static final String DEFAULT_DRIVER       = "oracle.jdbc.OracleDriver";
059    
060            // XMLファイル関連
061    //      private transient final String XmlFilename;
062    //      private final String XmlFilename;
063            private final String xmlFilename;                               // 5.7.2.2 (2014/01/24)
064    //      private static final String SCHEMA_FILENAME = "DBConfig.xsd";//xsdはfukurou.xml.jaxb.dbidパッケージに置?
065    
066    //      private transient final Map<String, EDbid> dbidMap = new HashMap<String, EDbid>();
067    //      private transient List<String> driverList = new ArrayList<String>();
068    //      private Map<String, EDbid> dbidMap = new HashMap<String, EDbid>();
069            private Map<String, EDbid> dbidMap = new LinkedHashMap<String, EDbid>();            // 5.6.7.0 (2013/07/27)
070    //      private List<String> driverList = new ArrayList<String>();
071            private List<String> driverList = new ArrayList<String>();
072    
073            // 5.6.7.0 (2013/07/27) プル?ンメニュー用の??の、キャ?ュ用変数?
074            private String codeKeyVal = null;               // 初めて要求されたときに、セ?します?
075    
076    //      private static final String CR = System.getProperty( "line.separator" );
077    
078            /* DBIDのキーの?を管?ます?5.1.9.0 (2010/08/01) */
079            // 5.5.2.0 (2012/05/01) property追?
080    //      private static final String[] DBID_INFO_KEYS
081    //                              = { "dbidKey", "url", "user", "password", "readonly"
082    //                                      , "mincount", "maxcount", "pooltime", "applicationInfo" };
083    //      private static final String[] DBID_INFO_KEYS
084    //                              = { "dbidKey", "url", "user", "password", "readonly"
085    //                                      , "mincount", "maxcount", "pooltime", "applicationInfo","property" };
086            // 5.6.6.0 (2013/07/05) 表?title)属?を追?
087            private static final String[] DBID_INFO_KEYS
088                                    = { "dbidKey", "title", "url", "user", "password", "readonly"
089                                            , "mincount", "maxcount", "pooltime", "applicationInfo","property" };
090    
091            /* DBDRIVERのキーのを管?ます?5.1.9.0 (2010/08/01) */
092            private static final String DBDRIVER_CLASS_KEY = "class";
093    
094            /**
095             * 初期値を使ってXMLを読み込?
096             * xmlFilenameの初期値は../DBConfig.xml
097             *
098             * @og.rev 4.3.1.1 (2008/08/23) 自??コンストラクターを呼ぶように修正
099             */
100            public DatabaseConfig() {
101                    this( "../DBConfig.xml" );
102            }
103    
104            /**
105             * XMLファイルの名前を指定して読み込?
106             *
107             * @og.rev 5.1.9.0 (2010/08/01) クラスロー??外からで?BConfig.xmlを取得できるようにする
108             * @og.rev 5.6.7.0 (2013/07/27) オブジェクト作?時に初期化も行っておきます?
109             * @og.rev 5.6.8.2 (2013/09/20) Tomcat8で、クラスロー??が変更されて?のでそ?対?
110             * @og.rev 5.7.2.2 (2014/01/24) WEB-INF/classes フォル?な?、xmlURL がnull になる対応?
111             *
112             * @param       xmlfile XMLファイルの名前
113             */
114            public DatabaseConfig( final String xmlfile ) {
115    //              xmlFilename = xmlfile;
116                    String fileName = null;
117    
118                    ClassLoader clsl        = getClass().getClassLoader();
119                    URL xmlURL                      = clsl.getResource( xmlfile );
120    
121                    if( xmlURL != null ) {
122                            fileName = xmlURL.getFile();
123                    }
124                    // 5.6.8.2 (2013/09/20) Tomcat8で、xmlURL が取得できなくなって?・・・よう??
125                    else {
126                            xmlURL = clsl.getResource( "/" );               // クラスパスのベ?スURL
127                            // 5.7.2.2 (2014/01/24) Tomcat7で、WEB-INF/classes フォル?な?、xmlURL がnull になる?
128                            if( xmlURL != null ) {
129                                    File temp = new File( xmlURL.getPath() , xmlfile );
130                                    if( temp.exists() ) { fileName = temp.getAbsolutePath(); }
131                            }
132                    }
133    
134                    // 5.1.9.0 (2010/08/01)  クラスロー??外からで?BConfig.xmlを取得できるようにする
135                    if( fileName == null && new File( xmlfile ).exists() ) {
136                            fileName = xmlfile;
137                    }
138    
139                    if( fileName == null ) {
140                            // 5.5.7.2 (2012/10/09) コメント追?
141                            String errMsg = "DBConfig.xmlが見つかりません?ile=[" + xmlfile + "]\n" 
142                                                                    + " WEB-INF/classes フォル?な?、相対パスで見つけることができません? ;
143                            throw new RuntimeException( errMsg );
144    //                      throw new RuntimeException( "DBConfig.xmlが見つかりません?ile=[" + xmlfile + "]" );
145                    }
146    
147                    xmlFilename                     = fileName;
148    //              System.out.println( xmlFilename );
149    
150                    init();                 // 5.6.7.0 (2013/07/27)
151            }
152    
153            /**
154             * dbidKeyをキーにしてExpandedDbid型でマップ??を返す?
155             * 存在しな??合?NULLを返します?
156             * キーが無??合に初期化を行う?
157             *
158             * @og.rev 4.0.0.1 (2007/12/04) EDbid#clone() ?
159             * @og.rev 5.6.7.0 (2013/07/27) synchronized メソ?にします?
160             *
161             * @param key XMLで登録したdbidKey
162             *
163             * @return EDbid型オブジェク?
164             */
165            public synchronized EDbid getDbid( final String key ) {
166    //              synchronized ( dbidMap ) {
167    //                      if( dbidMap.isEmpty() ) {
168    //                              init();
169    //                      }
170    
171                            return dbidMap.get( key.toUpperCase( Locale.JAPAN ) ) ;
172    //              }
173            }
174    
175            /**
176             * マップをクリアします?
177             * XMLファイルを?読み込みする場合に使用します?
178             *
179             * @og.rev 5.1.9.0 (2010/08/01) ドライバ?のリストもクリアする?
180             * @og.rev 5.6.7.0 (2013/07/27) synchronized メソ?にします?
181             */
182            public synchronized void reload() {
183    //              synchronized ( dbidMap ) {
184                            dbidMap.clear();
185    //              }
186    //              synchronized ( driverList ) {
187                            driverList.clear();
188    //              }
189                    init();
190            }
191    
192            /**
193             * 初期化??
194             *
195             * DB設定XMLファイル(DBConfig.xml)を読み込みます?
196             * こ?ファイルから、ドライバ?リスト?取得?DBIDのオブジェクト???の作??
197             * 行います?
198             * EDbidオブジェク?は、環?数で、?通?初期値を定義しておくことが可能です?
199             * ?として、REALM_URL、REALM_NAME、REALM_PASSWORD が設定可能です?
200             *
201             * ドライバ?リスト?取得後?Class.forName で、ドライバ?登録も行います?
202             *
203             * @og.rev 5.1.7.0 (2010/06/01) org.opengion.fukurou.xml.jaxb.dbid 関??
204             * @og.rev 5.6.7.0 (2013/07/27) dbidMap,driverList を書き込??ではなく?作?します?
205             */
206            private void init() {
207                    Document doc = DomParser.read( new File(xmlFilename) ) ;
208                    Element firstRoot = doc.getDocumentElement();
209    
210    //              List<String> driverList = getDriverList( firstRoot );
211    //              driverList = getDriverList( firstRoot );
212                    makeDriverList( firstRoot );                            // 5.6.7.0 (2013/07/27)
213    
214                    // 5.6.7.0 (2013/07/27) を?かけておきます?
215                    synchronized ( this ) {
216                            for( String dr : driverList ) {
217                                    try {
218                                            Class.forName( dr );
219                                    } catch ( ClassNotFoundException ex ) {
220                                            String errMsg = "ドライバクラスが見つかりません?" + dr + "]" ;
221                                            LogWriter.log( errMsg );
222                                            LogWriter.log( ex );
223                                    }
224                            }
225                    }
226    
227                    EDbid defDdbid = new EDbid();           // 初期値
228                    defDdbid.setUrl(                System.getenv( "REALM_URL" ) );
229                    defDdbid.setUser(               System.getenv( "REALM_NAME" ) );
230                    defDdbid.setPassword(   System.getenv( "REALM_PASSWORD" ) );
231    
232    //              dbidMap = getDbidMap( firstRoot,defDdbid );
233                    makeDbidMap( firstRoot,defDdbid );                              // 5.6.7.0 (2013/07/27)
234            }
235    
236            /**
237             * ドライバ?リストを取得します?
238             *
239             * DB設定XMLファイル(DBConfig.xml)の、class タグを取り込みます?
240             * こ?ファイルから、ドライバ?リストを取得します?
241             *
242             * ???段階?処?実行されます?
243             * 第?Step:DBConfig.xml から、ドライバ?リストを取?
244             * 第?Step:ドライバ?リストが存在しな??合?環?数の REALM_DRIVER からドライバ?を取?
245             * 第?Step:それでも存在しな??合?こ?クラスの DEFAULT_DRIVER 定数 からドライバ?を取?
246             *
247             * @og.rev 5.1.7.0 (2010/06/01) org.opengion.fukurou.xml.jaxb.dbid 関??
248             * @og.rev 5.1.9.0 (2010/08/01) ドライバ?のListをオブジェクト変数?
249             * @og.rev 5.6.7.0 (2013/07/27) driverList を書き込??ではなく?作?します?
250             * @og.rev 5.6.7.0 (2013/07/27) synchronized メソ?にします?
251             *
252             * @param       element DB設定XMLファイルのElementオブジェク?
253             */
254    //      private static List<String> getDriverList( final Element element ) {
255            private void makeDriverList( final Element element ) {
256    //              List<String> dList = new ArrayList<String>();
257    
258                    NodeList list = element.getElementsByTagName( "class" ) ;
259                    int num = list.getLength();
260                    for (int i = 0; i < num; i++) {
261                            Element cls = (Element)list.item(i);
262    //                      dList.add( cls.getTextContent() );
263                            driverList.add( cls.getTextContent() );
264                    }
265    
266    //              if( dList.isEmpty() ) {
267                    if( driverList.isEmpty() ) {
268                            String realmDriver = System.getenv( "REALM_DRIVER" );
269                            if( realmDriver != null && realmDriver.length() > 0 ) {
270    //                              dList.add( realmDriver );
271                                    driverList.add( realmDriver );
272                            }
273                    }
274    
275    //              if( dList.isEmpty() ) { dList.add( DEFAULT_DRIVER ); }
276                    if( driverList.isEmpty() ) { driverList.add( DEFAULT_DRIVER ); }
277    
278    //              return dList ;
279            }
280    
281            /**
282             * EDbidオブジェクト?マップを取得します?
283             *
284             * DB設定XMLファイル(DBConfig.xml)の、dbid タグを取り込みます?
285             * こ?ファイルから、EDbidオブジェクト?属???を取得し、オブジェクトを構築します?
286             *
287             * EDbidオブジェク?は、?期?をコピ?して、作?して?ます?
288             * EDbidオブジェクトをマップから取り?すキーとなる?dbidKey は、大?化して設定します?
289             *
290             * @og.rev 5.1.7.0 (2010/06/01) org.opengion.fukurou.xml.jaxb.dbid 関??
291             * @og.rev 5.1.9.0 (2010/08/01) Mapを返すように変更
292             * @og.rev 5.5.2.0 (2012/05/01) property追?
293             * @og.rev 5.6.6.0 (2013/07/05) 表?title)属?の取?
294             * @og.rev 5.6.7.0 (2013/07/27) ?MapをDBConfig.xmlの読み込み?変更?
295             * @og.rev 5.6.7.0 (2013/07/27) dbidMap を書き込??ではなく?作?します?
296             * @og.rev 5.6.7.0 (2013/07/27) synchronized メソ?にします?
297             * @og.rev 5.6.7.1 (2013/08/09) DEFAULT と、RESOURCE の DBIDキーがなければ、?部?作?します?
298             * @og.rev 5.6.8.0 (2013/09/06) RESOURCE の DBIDキーを?部作?時に、title も設定します?
299             *
300             * @param  element DB設定XMLファイルのElementオブジェク?
301             * @param  defDdbid 初期??の設定された、EDbidオブジェク?
302             */
303    //      private void makeDbidMap( final Element element , EDbid defDdbid ) {
304    //      private static Map<String,EDbid> getDbidMap( final Element element , EDbid defDdbid ) {
305            private void makeDbidMap( final Element element , EDbid defDdbid ) {
306    //              Map<String,EDbid> dMap = new HashMap<String,EDbid>();               // 5.6.7.0 (2013/07/27)
307    
308                    NodeList list = element.getElementsByTagName( "dbid" ) ;
309                    int num = list.getLength();
310                    for (int i = 0; i < num; i++) {
311                            Element ele = (Element)list.item(i);
312                            NodeList childs = ele.getChildNodes();
313                            int numChild = childs.getLength();
314    //                      EDbid dbid = new EDbid();
315                            EDbid dbid = defDdbid.clone();          // 初期値をコピ?して、作?
316                            for (int j = 0; j < numChild; j++) {
317                                    Node nd = childs.item(j);
318                                    if( nd.getNodeType() == Node.ELEMENT_NODE ) {
319                                            Element el = (Element)nd;
320                                            String tag = el.getTagName();
321                                            // dbidKey は、toUpperCase して、大??みとする?
322                                            if( "dbidKey".equals( tag ) )   {
323                                                    String dbidKey = el.getTextContent();
324                                                    if( dbidKey != null && dbidKey.length() > 0 ) {
325                                                            dbid.setDbidKey( dbidKey.toUpperCase( Locale.JAPAN ) );
326                                                    }
327                                            }
328                                            else if( "title".equals( tag ) )        { dbid.setTitle(        el.getTextContent() ); }                // 5.6.6.0 (2013/07/05) 表?title)属?の取?
329                                            else if( "url".equals( tag ) )          { dbid.setUrl(          el.getTextContent() ); }
330                                            else if( "user".equals( tag ) )         { dbid.setUser(         el.getTextContent() ); }
331                                            else if( "password".equals( tag ) ) { dbid.setPassword( el.getTextContent() ); }
332                                            else if( "readonly".equals( tag ) ) { dbid.setReadonly( el.getTextContent() ); }
333                                            else if( "mincount".equals( tag ) ) { dbid.setMincount( el.getTextContent() ); }
334                                            else if( "maxcount".equals( tag ) ) { dbid.setMaxcount( el.getTextContent() ); }
335                                            else if( "pooltime".equals( tag ) ) { dbid.setPooltime( el.getTextContent() ); }
336                                            else if( "applicationInfo".equals( tag ) ) { dbid.setApplicationInfo( el.getTextContent() ); }
337                                            else if ("property".equals( tag ) ) { dbid.addProp( el.getTextContent() ); } // 5.5.2.0 (2012/05/01)
338                                            else {
339                                                    System.err.println( "警告:dbid に新しい属?が?追?れて?す?" );
340                                            }
341                                    }
342                            }
343    //                      dbidMap.put( dbid.getDbidKey(), dbid );
344    //                      dMap.put( dbid.getDbidKey(), dbid );
345                            dbidMap.put( dbid.getDbidKey(), dbid );         // 5.6.7.0 (2013/07/27) 復活
346                    }
347    
348                    // 5.6.7.1 (2013/08/09) DEFAULT と、RESOURCE の DBIDキーがなければ、?部?作?します?
349                    EDbid dbid_D = dbidMap.get( "DEFAULT" );                // DEFAULT が存在するか確認する?
350                    if( dbid_D == null ) {
351                            dbid_D = defDdbid.clone();                                      // 初期値をコピ?
352                            dbid_D.setDbidKey( "DEFAULT" );
353                            dbidMap.put( "DEFAULT", dbid_D );
354                    }
355    
356                    EDbid dbid_R = dbidMap.get( "RESOURCE" );               // RESOURCE が存在するか確認する?
357                    if( dbid_R == null ) {
358                            dbid_R = dbid_D.clone();                                        // DEFAULT の DBIDをコピ?(?存在するは?
359                            dbid_R.setDbidKey( "RESOURCE" );
360                            dbid_R.setTitle( "RESOURCE" );                          // 5.6.8.0 (2013/09/06) title も設定します?
361                            dbidMap.put( "RESOURCE", dbid_R );
362                    }
363    
364    //              return dMap;
365            }
366    
367            /* ------------------------------------------------------------------------------------
368             *
369             * 以下?、DBConfig.xml編?のメソ?です?
370             * 編?のメソ?では、オブジェクト化されたDBID及?DBDRIVERの??は使用せずに?
371             * DBConfig.xmlからそ???を?度読み出して、SET/GETして?す?
372             * (オブジェクトとして依存して?のは、DBConfig.xmlのファイル名?みで?
373             *
374             * -------------------------------------------------------------------------------------
375             */
376            /**
377             * DBIDとして管?て??のキーの?を?列形式で返します?
378             *
379             * @og.rev 5.1.9.0 (2010/08/01) 新規作?
380             *
381             * @return ?のキー?
382             */
383            public static String[] getDbidInfoKeys() {
384    //              return DBID_INFO_KEYS;
385                    return DBID_INFO_KEYS.clone();
386            }
387    
388            /**
389             * 全てのDBIDの属???のリス?配?)で返します?
390             *
391             * 値の?につ?は、{@link #getDbidInfoKeys()}で返されるキーの?と同じです?
392             *
393             * @og.rev 5.1.9.0 (2010/08/01) 新規作?
394             * @og.rev 5.5.2.1 (2012/05/07) propertiesを??
395             * @og.rev 5.6.6.0 (2013/07/05) 表?title)属?を追?
396             * @og.rev 5.6.7.0 (2013/07/27) ?MapをDBConfig.xmlの読み込み?変更?
397             *
398             * @return 全てのDBIDの属???のリス?配?)
399             * @see #getDbidInfoKeys()
400             */
401            public synchronized String[][] getDbidInfo() {
402    //              Element ele = DomParser.read( new File(xmlFilename) ).getDocumentElement();
403    //              Map<String,EDbid> dMap = getDbidMap( ele , new EDbid() );
404    //              String[][] dbidInfo = new String[dMap.size()][DBID_INFO_KEYS.length];
405    
406                    String[][] dbidInfo = new String[dbidMap.size()][DBID_INFO_KEYS.length];
407                    int idx = 0;
408    //              for( EDbid dbid : dMap.values() ) {
409                    for( EDbid dbid : dbidMap.values() ) {
410                            dbidInfo[idx][0] = dbid.getDbidKey();
411                            dbidInfo[idx][1] = dbid.getTitle();                             // 5.6.6.0 (2013/07/05) 表?title)属?を追?
412                            dbidInfo[idx][2] = dbid.getUrl();
413                            dbidInfo[idx][3] = dbid.getUser();
414                            dbidInfo[idx][4] = dbid.getPassword();
415                            dbidInfo[idx][5] = String.valueOf( dbid.isReadonly() );
416                            dbidInfo[idx][6] = String.valueOf( dbid.getMincount() );
417                            dbidInfo[idx][7] = String.valueOf( dbid.getMaxcount() );
418                            dbidInfo[idx][8] = String.valueOf( dbid.getPooltime() );
419                            dbidInfo[idx][9] = String.valueOf( dbid.isApplicationInfo() );
420                            dbidInfo[idx][10]= String.valueOf( dbid.getProps().toString() ); // 5.5.2.1 (2012/05/07)
421                            idx++;
422                    }
423                    // 5.6.7.0 (2013/07/27) ?MapをDBConfig.xmlの読み込み?変更(なので、?)?
424    //              dbidSort( dbidInfo );
425                    return dbidInfo;
426            }
427    
428            /**
429             * 全てのDBIDの属???のリス?配?)をセ?します?
430             *
431             * こ?メソ?を呼び出すと、DBConfig.xmlで定義されて?DBID?????削除??
432             * そ?上で、引数のDBID???をDBConfig.xmlに書き込みます?
433             *
434             * 値の?につ?は、{@link #getDbidInfoKeys()}で返されるキーの?と同じです?
435             *
436             * 書き込みの直前に、同じフォル?タイ?タンプを付加したバックア??ファイルを作?します?
437             *
438             * @og.rev 5.1.9.0 (2010/08/01) 新規作?
439             * @og.rev 5.6.7.0 (2013/07/27) ?MapをDBConfig.xmlの読み込み?変更?
440             *
441             * @param dbidVals 全てのDBIDの属???のリス?配?)
442             * @see #getDbidInfoKeys()
443             */
444            public void setDbidInfo( final String[][] dbidVals ) {
445                    FileUtil.copy( xmlFilename, xmlFilename + "_" + System.currentTimeMillis() );
446    
447                    Document doc = DomParser.read( new File(xmlFilename) ) ;
448                    Element firstRoot = doc.getDocumentElement();
449                    deleteChildElements( firstRoot, "dbid" );
450    
451                    if( dbidVals != null && dbidVals.length > 0 ) {
452                            // 5.6.7.0 (2013/07/27) ?MapをDBConfig.xmlの読み込み?変更(なので、?)?
453    //                      dbidSort( dbidVals );
454                            for( int i=0; i<dbidVals.length; i++ ) {
455                                    Element newEle = doc.createElement( "dbid" );
456                                    for( int j=0; j<dbidVals[i].length; j++ ) {
457                                            Element newChEle = doc.createElement( DBID_INFO_KEYS[j] );
458                                            newChEle.setTextContent( dbidVals[i][j] );
459                                            newEle.appendChild( newChEle );
460                                    }
461                                    firstRoot.appendChild( newEle );
462                                    firstRoot.appendChild( doc.createTextNode( "\n\n" ) );
463                            }
464                    }
465    
466                    DomParser.write( new File(xmlFilename), doc );
467    
468                    reload();               // 5.6.7.0 (2013/07/27) DBIDの属???のリストを更新後?初期化します?
469            }
470    
471            /**
472             * DBIDの配?をソートします?
473             * ソート?方法としては?
474             *  ?EFAULTのDBIDは?初め
475             *  ②DEFAULT以外?、DBID?
476             * となります?
477             *
478             * @og.rev 5.6.7.0 (2013/07/27) ?MapをDBConfig.xmlの読み込み?変更(なので、?)?
479             *
480             * @param dbidVals 全てのDBIDの属???のリス?配?)
481             */
482    //      private static void dbidSort( final String[][] dbidVals ) {
483    //              Arrays.sort( dbidVals, new Comparator<String[]>() {
484    //                       public int compare( String[] s1, String[] s2 ) {
485    //                               if( "DEFAULT".equals( s1[0] ) ) {
486    //                                       return -1;
487    //                               }
488    //                               else if( "DEFAULT".equals( s2[0] ) ) {
489    //                                       return 1;
490    //                               }
491    //                               return s1[0].compareTo( s2[0] );
492    //                       }
493    //              }
494    //              );
495    //      }
496    
497            /**
498             * DBドライバ?の属?キーを返します?
499             *
500             * @og.rev 5.1.9.0 (2010/08/01) 新規作?
501             *
502             * @return      DBドライバ?の属?キー
503             */
504            public static String getDriverKey() {
505                    return DBDRIVER_CLASS_KEY;
506            }
507    
508            /**
509             * DBドライバ?のリス?配?)を返します?
510             *
511             * @og.rev 5.1.9.0 (2010/08/01) 新規作?
512             * @og.rev 5.6.7.0 (2013/07/27) driverList を書き込??ではなく?作?します?
513             *
514             * @return      DBドライバ?リス?配?)
515             */
516            public synchronized String[] getDriverList() {
517    //              Element ele = DomParser.read( new File(xmlFilename) ).getDocumentElement();
518    //              String [] rtn = getDriverList( ele ).toArray( new String[0] );
519    
520                    String [] rtn = driverList.toArray( new String[driverList.size()] );
521    //              driverSort( rtn );
522                    return rtn;
523            }
524    
525            /**
526             * DBドライバ?のリス?配?)をセ?します?
527             *
528             * こ?メソ?を呼び出すと、DBConfig.xmlで定義されて?class???削除??
529             * そ?上で、引数のDBドライバ??をDBConfig.xmlに書き込みます?
530             *
531             * 書き込みの直前に、同じフォル?タイ?タンプを付加したバックア??ファイルを作?します?
532             *
533             * @og.rev 5.1.9.0 (2010/08/01) 新規作?
534             * @og.rev 5.6.7.0 (2013/07/27) DBドライバ?のリストを更新後?初期化します?
535             *
536             * @param drivers DBドライバ?のリス?配?)
537             */
538            public void setDriverList( final String[] drivers ) {
539                    FileUtil.copy( xmlFilename, xmlFilename + "_" + System.currentTimeMillis() );
540    
541                    Document doc = DomParser.read( new File(xmlFilename) );
542                    Element firstRoot = doc.getDocumentElement();
543    
544                    Element parent = (Element)firstRoot.getElementsByTagName( "dbDriver" ).item( 0 );
545                    deleteChildElements( parent, "class" );
546    
547                    if( drivers != null && drivers.length > 0 ) {
548    //                      driverSort( drivers );
549                            for( int i=0; i<drivers.length; i++ ) {
550                                    Element newEle = doc.createElement( "class" );
551                                    newEle.setTextContent( drivers[i] );
552                                    parent.appendChild( newEle );
553                            }
554                    }
555    
556                    DomParser.write( new File(xmlFilename), doc );
557    
558                    reload();               // 5.6.7.0 (2013/07/27) DBドライバ?のリストを更新後?初期化します?
559            }
560    
561    
562            /**
563             * DBID??のキーとタイトルから、?ル?ンメニューを作?するための??を取得します?
564             *
565             * こ?メソ?を呼び出すと、DBConfig.xmlで定義されて? dbidKey と?title 属?から?
566             * 「key1:val1 key2:val2 ・・・」と???を作?します?
567             * これを利用すれば、?ル?ンメニューが簡単に作?できます?
568             *
569             * @og.rev 5.6.7.0 (2013/07/27) プル?ンメニュー用の??を作?します?
570             * @og.rev 5.6.7.1 (2013/08/09) 表?title)属?のスペ?ス対?
571             *
572             * @return プル?ンメニューを作?するための??
573             */
574            public synchronized String getCodeKeyVal() {
575                    if( codeKeyVal == null ) {
576                            StringBuilder buf = new StringBuilder();
577                            for( EDbid dbid : dbidMap.values() ) {
578                                    String key = dbid.getDbidKey();
579                                    String lbl = StringUtil.nval( dbid.getTitle() , key );
580    //                              buf.append( " " ).append( key ).append( ":" ).append( lbl );
581                                    if( lbl.indexOf( ' ' ) >= 0 ) {                                                                      // 5.6.7.1 (2013/08/09) スペ?ス対?
582                                            buf.append( " " ).append( key ).append( ":\"" ).append( lbl ).append( "\"" );
583                                    }
584                                    else {
585                                            buf.append( " " ).append( key ).append( ":" ).append( lbl );
586                                    }
587                            }
588    
589                            codeKeyVal = buf.substring( 1 );                // 先?のスペ?スを削除
590                    }
591    
592                    return codeKeyVal;
593            }
594    
595            /**
596             * DBドライバ?の配?をソートします?
597             * ソート?方法としては?
598             *  ?EFAULT_DRIVERのDBは?初め
599             *  ②DEFAULT以外?、DBID?
600             * となります?
601             *
602             * @og.rev 5.6.7.0 (2013/07/27) ?ListをDBConfig.xmlの読み込み?変更(なので、?)?
603             *
604             * @param drivers 全てのDBIDの属???のリス?配?)
605             */
606    //      private static void driverSort( final String[] drivers ) {
607    //              Arrays.sort( drivers, new Comparator<String>() {
608    //                       public int compare( String s1, String s2 ) {
609    //                               if( DEFAULT_DRIVER.equals( s1 ) ) {
610    //                                       return -1;
611    //                               }
612    //                               else if( DEFAULT_DRIVER.equals( s2 ) ) {
613    //                                       return 1;
614    //                               }
615    //                               return s1.compareTo( s2 );
616    //                       }
617    //              }
618    //              );
619    //      }
620    
621            /**
622             * 親要?基点として、引数で?されたタグ名を持つ子要?削除します?
623             *
624             * @og.rev 5.6.7.0 (2013/07/27) staticメソ? ?イスタンスメソ?に変更
625             *
626             * @param parent 親要?
627             * @param childTagName 削除する子要??タグ?
628             */
629    //      private static void deleteChildElements( final Element parent, final String childTagName ) {
630            private void deleteChildElements( final Element parent, final String childTagName ) {
631                    Node child = parent.getFirstChild();
632                    boolean isDel = false;
633                    while ( child != null ) {
634                            // エレメント間の改行Cも削除するため、次の異なる要?来るまでは削除し続けます?
635                            if( child.getNodeType() == Node.ELEMENT_NODE ) {
636    //                              if( ((Element)child).getTagName().equals( childTagName ) ) {
637                                    if( ((Element)child).getTagName().equalsIgnoreCase( childTagName ) ) {
638                                            isDel = true;
639                                    }
640                                    else {
641                                            isDel = false;
642                                    }
643                            }
644    
645                            Node next = child.getNextSibling();
646                            if( isDel ) {
647                                    parent.removeChild( child );
648                            }
649                            child = next;
650                    }
651            }
652    }