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