    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.servlet;
    017
    018import java.io.File;
    019import java.io.IOException;
    020import java.io.PrintWriter;
    021import java.lang.reflect.Field;
    022import java.net.URL;
    023import java.util.Enumeration;
    024import java.util.Map;
    025import java.util.jar.JarEntry;
    026import java.util.jar.JarFile;
    027
    028import javax.servlet.ServletContext;
    029import javax.servlet.ServletException;
    030import javax.servlet.http.HttpServlet;
    031import javax.servlet.http.HttpServletRequest;
    032import javax.servlet.http.HttpServletResponse;
    033import javax.servlet.http.HttpSession;
    034
    035import org.opengion.fukurou.db.ConnectionFactory;
    036import org.opengion.fukurou.util.Attributes;
    037import org.opengion.fukurou.util.HybsEntry;
    038import org.opengion.fukurou.util.StringUtil;
    039import org.opengion.fukurou.util.Closer ;                               // 5.5.2.6 (2012/05/25)
    040import org.opengion.hayabusa.common.BuildNumber;
    041import org.opengion.hayabusa.common.HybsSystem;
    042import org.opengion.hayabusa.common.SystemManager;
    043import org.opengion.hayabusa.common.SystemParameter;
    044import org.opengion.hayabusa.common.UserSummary;
    045
    046/**
    047 * サーバー管理情報を取得するAdminサーブレットです。
    048 *
    049 * 引数(URL)に応じて、サーバーの状態結果を返します。
    050 * 一般には、http://サーバー:ポート/システムID/jsp/admin?COMMAND=コマンド の
    051 * 形式のURL でアクセスします。
    052 *
    053 *  ・COMMAND=infomation
    054 *     【サーバー情報】
    055 *        ＯＳ情報      = Windows 7 Service Pack 1
    056 *        サーバー名    = 10374232-0004 ( 172.27.26.192 )
    057 *        サーブレット  = Apache Tomcat/7.0.42
    058 *        TOMCAT_HOME   = C:/opengionV6/uap/bin//../../apps/tomcat7.0.42
    059 *        JDKバージョン = Java HotSpot(TM) Server VM 23.25-b01
    060 *        JAVA_HOME     = C:/opengionV6/apps/jdk170u25/jre
    061 *
    062 *     【実行環境】
    063 *        REAL_PATH     = C:/opengionV6/uap/webapps/gf/
    064 *        バージョンNo  = 6.0.0.0 Release6 Builds (2013233)
    065 *        作成日時      = 2013/08/21 14:57:29
    066 *
    067 *     【ログイン情報】
    068 *        ログイン人数  = 2 名 ( 明細情報 )
    069 *
    070 *     【メモリ情報】
    071 *        空きメモリ    = 15977 [KByte]
    072 *        合計メモリ    = 32448 [KByte]
    073 *        使用率        = 50 [％]
    074 *
    075 *  ・COMMAND=close
    076 *       リソース情報のキャッシュを全てクリアします。
    077 *
    078 *  ・COMMAND=loginUser
    079 *       現在のログインユーザーの明細情報を表示します。
    080 *       SORT=[JNAME,ID,ROLES,IPADDRESS,LOGINTIME] ソートキー
    081 *       DIREC=[true,false] true:昇順/false:降順
    082 *
    083 *  ・COMMAND=plugin
    084 *       現在のプラグインのバージョン情報を表示します。
    085 *
    086 *  ・COMMAND=systemResource
    087 *       現在のシステムリソースの設定情報を表示します。
    088 *
    089 *  ・COMMAND=AccessStop
    090 *       アクセスストップフィルターの制御(停止、許可)を行います。
    091 *
    092 * @og.rev 3.5.3.0 (2003/10/27) Admin JSP を Servlet化して、エンジンと共に供給します。
    093 * @og.rev 4.0.0.0 (2005/08/31) プラグインのバージョン情報の表示機能を追加
    094 * @og.group その他機能
    095 *
    096 * @version  4.0
    097 * @author   Kazuhiko Hasegawa
    098 * @since    JDK5.0,
    099 */
    100public final class HybsAdmin extends HttpServlet {
    101        private static final long serialVersionUID = 4000 ;     // 4.0.0 (2005/01/31)
    102
    103        private static final String CR = HybsSystem.CR ;
    104
    105        private static final String JSP = HybsSystem.sys( "JSP" );      // jspフォルダの正規パス
    106
    107        private static final String HEADER =
    108                "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"                                                                                             + CR +
    109                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\""                                                   + CR +
    110                "    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"                                                   + CR +
    111                "<html xmlns=\"http://www.w3.org/1999/xhtml\" >"                                                                                  + CR +
    112                "<head>"                                                                                                                                                                  + CR +
    113                "    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />"                           + CR +
    114                "    <meta http-equiv=\"Content-Style-Type\" content=\"text/css\" />"                                             + CR +
    115                "    <link rel=\"stylesheet\" href=\"" + JSP + "/common/default.css\" type=\"text/css\" />"       + CR +
    116                "    <link rel=\"stylesheet\" href=\"" + JSP + "/custom/custom.css\" type=\"text/css\" />"                                + CR +
    117                "    <title>Hybs Admin</title>"                                                                                                                             + CR +
    118                "</head>"                                                                                                                                                                 + CR;
    119
    120        // 3.5.3.1 (2003/10/31) User情報のテーブルの設定を、システムリソース より行う。
    121        private static final String TABLE_HEADER = getTableHeaderTag() ;
    122
    123        private static final String OS_INFO      = HybsSystem.sys( "OS_INFO"      );            // Windows 7 Service Pack 1
    124        private static final String SERVER_INFO  = HybsSystem.sys( "SERVER_INFO"  );            // 10374232-0004 ( 200.1.50.239 )
    125        private static final String SERVLET_INFO = HybsSystem.sys( "SERVLET_INFO" );            // Apache Tomcat/7.0.39
    126        private static final String REAL_PATH    = HybsSystem.sys( "REAL_PATH"    );            // C:/opengion/uap/webapps/gf/
    127//      private static final String TOMCAT_WORK  = HybsSystem.sys( "TOMCAT_WORK"  );            // 5.6.7.3 (2013/08/23) TOMCAT_HOME に置き換え、廃止
    128        private static final String TOMCAT_HOME  = HybsSystem.sys( "TOMCAT_HOME"  );            // C:/opengion/apps/tomcat5.5.17
    129        private static final String JDK_INFO     = HybsSystem.sys( "JDK_INFO"     );            // Java HotSpot(TM) Server VM 23.25-b01
    130        private static final String JAVA_HOME    = HybsSystem.sys( "JAVA_HOME"    );            // C:/opengion/apps/jdk170u25/jre
    131        private static final String ENGINE_INFO  = HybsSystem.sys( "ENGINE_INFO"  );            // 5.6.6.0 Release5 Builds (2013182)
    132
    133        /**
    134         * GET メソッドが呼ばれたときに実行します。
    135         *
    136         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
    137         * @og.rev 3.5.4.1 (2003/12/01) getAdminLink() メソッドを追加
    138         *
    139         * @param       req     HttpServletRequestオブジェクト
    140         * @param       res     HttpServletResponseオブジェクト
    141         *
    142         * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
    143         * @throws IOException 入出力エラーが発生したとき
    144         */
    145        @Override
    146        public void doGet( final HttpServletRequest req, final HttpServletResponse res)
    147                                                                throws ServletException, IOException {
    148
    149                res.setContentType( "text/html; charset=UTF-8" );
    150                PrintWriter out = res.getWriter();
    151
    152                String command = req.getParameter( "COMMAND" );
    153
    154                out.println( HEADER );
    155                out.println("<body>");
    156
    157                out.print("<h2>");
    158                out.print( req.getServerName() );
    159                out.print( ":" );
    160                out.print( req.getServerPort() );
    161                out.print( req.getContextPath() );
    162                out.println("</h2>");
    163
    164                if( "infomation".equalsIgnoreCase( command ) ) {
    165                        out.print( getInfomation() );
    166                }
    167                else if( "close".equalsIgnoreCase( command ) ) {
    168                        out.print( getCloseMessage( req.getSession() ) );
    169                }
    170                else if( "loginUser".equalsIgnoreCase( command ) ) {
    171                        String sort  = req.getParameter( "sort" );
    172                        String direc = req.getParameter( "direc" );
    173                        boolean dir = (direc == null) ? true :  Boolean.valueOf( direc ).booleanValue();
    174                        out.print( getLoginUser(sort,dir) );
    175                }
    176                else if( "plugin".equalsIgnoreCase( command ) ) {
    177                        out.print( getPlugInInfo() );
    178                }
    179                else if( "taglib".equalsIgnoreCase( command ) ) {
    180                        out.print( getTaglibInfo() );
    181                }
    182                else if( "systemResource".equalsIgnoreCase( command ) ) {
    183                        out.print( getSystemResource() );
    184                }
    185                else if( "AccessStop".equalsIgnoreCase( command ) ) {
    186                        out.print( getAccessStop() );
    187                }
    188                else {
    189                        out.print( getAdminLink() );            // 3.5.4.1 (2003/12/01) 追加
    190                }
    191
    192                out.println("</body></html>");
    193        }
    194
    195        /**
    196         * infomation 情報を作成します。
    197         *
    198         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
    199         * @og.rev 5.6.7.3 (2013/08/23) TOMCAT_WORKは、TOMCAT_HOME に置き換えます。
    200         *
    201         * @return      infomation情報
    202         */
    203        private String getInfomation() {
    204                // 4.0.0 (2005/01/31) ログイン数の取得方法の変更。
    205                int loginCount = SystemManager.getRunningCount() ;
    206
    207                int freeMemory  = (int)( Runtime.getRuntime().freeMemory()/1024 ) ;
    208                int totalMemory = (int)( Runtime.getRuntime().totalMemory()/1024 );
    209                int useMemoryRatio = (((totalMemory - freeMemory) * 100 )/totalMemory) ;
    210
    211                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    212
    213                rtn.append( "<table border = \"0px\" >" ).append( CR );
    214                tableTr1( rtn,"サーバー情報" );
    215                tableTr( rtn,"ＯＳ情報"             , OS_INFO               );
    216                tableTr( rtn,"サーバー名"    , SERVER_INFO   );
    217                tableTr( rtn,"サーブレット"   , SERVLET_INFO  );
    218//              tableTr( rtn,"TOMCAT_WORK"      , TOMCAT_WORK   );              // 5.6.7.3 (2013/08/23) TOMCAT_HOME に置き換え、廃止
    219                tableTr( rtn,"TOMCAT_HOME"      , TOMCAT_HOME   );              // 5.6.7.3 (2013/08/23)
    220                tableTr( rtn,"JDKバージョン", JDK_INFO               );
    221                tableTr( rtn,"JAVA_HOME"        , JAVA_HOME             );
    222
    223                tableTr1( rtn,"実行環境" );
    224                tableTr( rtn,"REAL_PATH"        , REAL_PATH             );
    225                tableTr( rtn,"バージョンNo"  , ENGINE_INFO   );
    226                tableTr( rtn,"作成日時"             , BuildNumber.TIMESTAMP );
    227
    228                tableTr1( rtn,"ログイン情報" );
    229                tableTr( rtn,"ログイン人数"   , String.valueOf( loginCount )," 名 ","( <a href=\"admin?COMMAND=loginUser\">明細情報</a> )" );
    230
    231                tableTr1( rtn,"メモリ情報" );
    232                tableTr( rtn,"空きメモリ"    , String.valueOf( freeMemory )          , " [KByte]" );
    233                tableTr( rtn,"合計メモリ"    , String.valueOf( totalMemory )         , " [KByte]" );
    234                tableTr( rtn,"使用率"              , String.valueOf( useMemoryRatio )      , " [％]"    );
    235
    236                rtn.append( "</table>" ).append( CR );
    237                rtn.append( CR );
    238
    239//              rtn.append( "   <tr><td colspan = \"4\">サーバー情報</td></tr>" ).append( CR );
    240//              rtn.append( "   <tr><td></td><td>ＯＳ情報</td><td>=</td><td>" ).append( OS_INFO ).append( "</td></tr>" ).append( CR );
    241//              rtn.append( "   <tr><td></td><td>サーバー名</td><td>=</td><td>" ).append( SERVER_INFO ).append( "</td></tr>" ).append( CR );
    242//              rtn.append( "   <tr><td></td><td>サーブレット</td><td>=</td><td>" ).append( SERVLET_INFO ).append( "</td></tr>" ).append( CR );
    243//              rtn.append( "   <tr><td></td><td>REAL_PATH</td><td>=</td><td>" ).append( REAL_PATH ).append( "</td></tr>" ).append( CR );
    244//              rtn.append( "   <tr><td></td><td>TOMCAT_WORK</td><td>=</td><td>" ).append( TOMCAT_WORK ).append( "</td></tr>" ).append( CR );
    245//              rtn.append( "   <tr><td></td><td>JDKバージョン</td><td>=</td><td>" ).append( JDK_INFO ).append( "</td></tr>" ).append( CR );
    246//              rtn.append( "   <tr><td></td><td>JAVA_HOME</td><td>=</td><td>" ).append( JAVA_HOME ).append( "</td></tr>" ).append( CR );
    247//              rtn.append( "   <th><td></td><td colspan = \"2\"></td></th>" ).append( CR );
    248//              rtn.append( "   <tr><td colspan = \"4\">エンジンバージョン</td></tr>" ).append( CR );
    249//              rtn.append( "   <tr><td></td><td>バージョンNo</td><td>=</td><td>" ).append( ENGINE_INFO ).append( "</td></tr>" ).append( CR );
    250//              rtn.append( "   <tr><td></td><td>作成日時</td><td>=</td><td>" ).append( BuildNumber.TIMESTAMP ).append( "</td></tr>" ).append( CR );
    251//              rtn.append( "   <th><td></td><td colspan = \"2\"></td></th>" ).append( CR );
    252//              rtn.append( "   <tr><td colspan = \"4\">ログインユーザー</td></tr>" ).append( CR );
    253//              rtn.append( "   <tr><td></td><td>ログイン人数    </td><td>=</td><td>" ).append( loginCount ).append( " 名 " );
    254//              rtn.append( "( <a href=\"admin?COMMAND=loginUser\">明細情報</a> )</td></tr>" ).append( CR );
    255//              rtn.append( "   <tr><td colspan = \"4\">メモリ情報</td></tr>" ).append( CR );
    256//              rtn.append( "   <tr><td></td><td>空きメモリ</td><td>=</td><td>" ).append( freeMemory ).append( " [KByte]</td></tr>" ).append( CR );
    257//              rtn.append( "   <tr><td></td><td>合計メモリ</td><td>=</td><td>" ).append( totalMemory ).append( " [KByte]</td></tr>" ).append( CR );
    258//              rtn.append( "   <tr><td></td><td>使用率</td><td>=</td><td>" ).append( useMemoryRatio ).append( " [％]</td></tr>" ).append( CR );
    259//              rtn.append( "</table>" ).append( CR );
    260//              rtn.append( CR );
    261
    262                rtn.append( "<table width=\"50%\" frame=\"box\" border = \"1px\" cellspacing=\"0px\" cellpadding=\"0px\" >" ).append( CR );
    263//              rtn.append( "   <tr><td width=\"" ).append( useMemoryRatio ).append( "%\" bgcolor=\"red\" >" ).append( CR );
    264//              rtn.append( "           <img width=\"100%\" height=\"10px\" src=\"" ).append( JSP ).append( "/image/space.gif\" alt=\"" ).append( useMemoryRatio ).append( "%\"></td>" ).append( CR );
    265//              rtn.append( "           <td></td>" ).append( CR );
    266//              rtn.append( "   </tr>" ).append( CR );
    267                rtn.append( "   <tr><td align=\"center\" width=\"" ).append( useMemoryRatio ).append( "%\" bgcolor=\"red\" >" ).append( CR );
    268                rtn.append( useMemoryRatio ).append( "%</td>" ).append( CR );
    269                rtn.append( "           <td align=\"center\">" ).append( 100-useMemoryRatio ).append( "%</td>" ).append( CR );
    270                rtn.append( "   </tr>" ).append( CR );
    271                rtn.append( "</table>" ).append( CR );
    272
    273                rtn.append( "<hr />" ).append( CR );
    274                rtn.append( "<pre>" ).append( CR );
    275                rtn.append( ConnectionFactory.information() ).append( CR );
    276                rtn.append( "</pre>" ).append( CR );
    277
    278                return rtn.toString();
    279        }
    280
    281        /**
    282         * infomation 情報を作成します。
    283         *
    284         * @og.rev 5.6.6.0 (2013/07/05) &lt;/td&gt;&lt;/tr&gt;漏れ追加
    285         * @og.rev 5.6.7.3 (2013/08/23) 前後に、【】を付けます。
    286         *
    287         * @param       buf     情報登録用のStringBuilder(出力と同じオブジェクト)
    288         * @param       key     キー
    289         *
    290         * @return      infomation情報
    291         */
    292        private StringBuilder tableTr1( final StringBuilder buf, final String key ) {
    293//              buf.append( "<tr><td colspan = \"4\">" ).append( key ).append( CR );
    294//              buf.append( "<tr><td colspan=\"4\"><b>" ).append( key ).append( "</b></td></tr>" ).append( CR );            // td,tr 漏れ追加
    295                buf.append( "<tr><td colspan=\"4\"><b>【" ).append( key ).append( "】</b></td></tr>" ).append( CR );  // 【】追加
    296                return buf ;
    297        }
    298
    299        /**
    300         * infomation 情報を作成します。
    301         *
    302         * @og.rev 5.6.6.0 (2013/07/05) 最初の td に、全角スペース２個 追加
    303         *
    304         * @param       buf     情報登録用のStringBuilder(出力と同じオブジェクト)
    305         * @param       key     キー
    306         * @param       val     値の可変長引数
    307         *
    308         * @return      infomation情報
    309         */
    310        private StringBuilder tableTr( final StringBuilder buf, final String key, final String... val ) {
    311//              buf.append( "\t<tr><td></td><td>" ).append( key ).append( "</td><td>=</td><td>" );
    312                buf.append( "<tr><td width=\"20px\">　</td><td>" ).append( key ).append( "</td><td> = </td><td>" );                      // 段を作成する為に、width指定 追加
    313                for( int i=0; i<val.length; i++ ) {
    314                        buf.append( val[i] );
    315                }
    316                buf.append( "</td></tr>" ).append( CR );
    317                return buf ;
    318        }
    319
    320        /**
    321         * close 情報を作成します。
    322         *
    323         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
    324         * @og.rev 3.6.0.0 (2004/09/17) CalendarFactory.clear() を追加します。
    325         * @og.rev 4.0.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
    326         * @og.rev 4.1.0.2 (2008/01/29) UserInfoをsessionから消去する(超暫定対応)
    327         * @og.rev 5.6.6.0 (2013/07/05) UserSummary の削除処理は、SystemManager から行う。
    328         *
    329         * @param       session HttpSessionオブジェクト
    330         *
    331         * @return      close情報
    332         */
    333        private String getCloseMessage( final HttpSession session ) {
    334
    335                // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
    336                SystemManager.allClear( false ) ;
    337
    338                ServletContext context = session.getServletContext();
    339                Map<String,String> param = SystemParameter.makeSystemParameter( context );
    340                HybsSystem.setInitialData( param );                     // 4.0.0 (2005/01/31)
    341
    342                // 5.6.6.0 (2013/07/05) UserSummary の削除処理は、SystemManager から行う。
    343                SystemManager.removeSession( session ) ;
    344
    345//              UserSummary userInfo = (UserSummary)session.getAttribute( HybsSystem.USERINFO_KEY );
    346////            if( userInfo != null ) { userInfo.clear(); }
    347//              if( userInfo != null ) { // 4.1.0.2 (2008/01/29)
    348//                      userInfo.clear();
    349//                      session.removeAttribute( HybsSystem.USERINFO_KEY );
    350//              }
    351
    352                String rtn = "<pre>"
    353                                        + "キャッシュ情報をクリアーしました。"
    354                                        + CR
    355                                        + "ユーザー情報の初期化に関しては、ブラウザを閉じて、再ログインが必要です。"
    356                                        + CR
    357                                        + ConnectionFactory.information()
    358                                        + "</pre>" ;
    359                return rtn ;
    360        }
    361
    362        // 5.6.6.0 (2013/07/05) getLoginUser( String,boolean ) で、指定するキーを配列で持っておきます。
    363        // キーは、SystemManager.getRunningUserSummary 処理内で大文字化されるため、この配列は、表示用と兼用します。
    364        private static final String[] USER_KEYS = new String[] { "ID","Jname","Roles","IPAddress","LoginTime","LastAccess","LastGamenNm" };
    365
    366        /**
    367         * loginUser 情報を作成します。
    368         *
    369         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
    370         * @og.rev 3.8.5.3 (2006/08/07) ユーザー情報をソートするためのキー情報を追加
    371         * @og.rev 3.8.7.0 (2006/12/15) USER.LASTACCESS情報を追加します。
    372         * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属性(CLS_NM)から、DBTYPEに変更
    373         * @og.rev 4.4.0.1 (2009/08/08) 最終ログイン画面名称を追加
    374         * @og.rev 5.6.6.0 (2013/07/05) table作成処理を、変更します。
    375         *
    376         * @param       sort    ソートするキー項目を指定
    377         * @param       direc   ソートする方向 [true:昇順/false:降順]
    378         *
    379         * @return      loginUser情報
    380         */
    381        private String getLoginUser( final String sort,final boolean direc ) {
    382                // 4.0.0 (2005/01/31) ログイン数の取得方法の変更。
    383                int loginCount = SystemManager.getRunningCount() ;
    384
    385                // 4.0.0 (2005/01/31)
    386                UserSummary[] userInfos = SystemManager.getRunningUserSummary( sort,direc );
    387
    388                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    389
    390                rtn.append( "現在 " ).append( loginCount ).append( " 名の方がログイン中です。" );
    391                rtn.append( CR );
    392
    393                rtn.append( "<table " ).append( TABLE_HEADER ).append( " >" ).append( CR );
    394                rtn.append( " <thead><tr><th>No</th>" );
    395
    396                // 5.6.6.0 (2013/07/05) table作成処理を、変更します。
    397                for( String sortKey : USER_KEYS ) {
    398                        rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=" ).append( sortKey )
    399                                .append( "&direc=" ).append( !direc )
    400                                .append( "\">" ).append( sortKey ).append( "</a></th>" );
    401                }
    402
    403//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=ID&direc="                        ).append( !direc );
    404//              rtn.append(                             "\">UserID</a></th>" );
    405//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=JNAME&direc="             ).append( !direc );
    406//              rtn.append(                             "\">Jname</a></th>" );
    407//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=ROLES&direc="             ).append( !direc );
    408//              rtn.append(                             "\">Roles</th>" );
    409//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=IPADDRESS&direc=" ).append( !direc );
    410//              rtn.append(                             "\">IPAddress</a></th>" );
    411//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=LOGINTIME&direc=" ).append( !direc );
    412//              rtn.append(                             "\">LoginTime</a></th>" );
    413//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=LASTACCESS&direc="        ).append( !direc );
    414//              rtn.append(                             "\">LastAccess</a></th>" );
    415//              rtn.append( "  <th><a href=\"?COMMAND=loginUser&sort=LASTGAMENNM&direc=").append( !direc ); // 4.4.0.1 (2009/08/08)
    416//              rtn.append(                             "\">LastGamenName</a></th>" );
    417                rtn.append( " </tr></thead>" ).append( CR );
    418                rtn.append( " <colgroup class=\"S9\" />" ).append( CR );
    419                rtn.append( " <colgroup class=\"X\" span=\"6\" />" ).append( CR );
    420                rtn.append( CR );
    421
    422                for( int i=0; i<userInfos.length; i++ ) {
    423                        UserSummary userInfo = userInfos[i] ;
    424                        rtn.append( " <tr class=\"row_" ).append( i%2 ).append( "\" >" ).append( CR );
    425                        rtn.append( "  <td>" ).append( String.valueOf( i+1 )   ).append( "</td>" ).append( CR );
    426                        rtn.append( "  <td>" ).append( userInfo.getUserID()    ).append( "</td>" ).append( CR );
    427                        rtn.append( "  <td>" ).append( userInfo.getJname()     ).append( "</td>" ).append( CR );
    428                        rtn.append( "  <td>" ).append( userInfo.getRoles()     ).append( "</td>" ).append( CR );
    429                        rtn.append( "  <td>" ).append( userInfo.getIPAddress() ).append( "</td>" ).append( CR );
    430                        rtn.append( "  <td>" ).append( HybsSystem.getDate( userInfo.getLoginTime() ) ).append( "</td>" ).append( CR );
    431                        rtn.append( "  <td>" ).append( userInfo.getAttribute( "LASTACCESS") ).append( "</td>" ).append( CR );
    432                        rtn.append( "  <td>" ).append( StringUtil.nval( userInfo.getAttribute( "LASTGAMENNM"), "" ) ).append( "</td>" ).append( CR );  // 4.4.0.1 (2009/08/08)
    433                        rtn.append( " </tr>" ).append( CR );
    434                }
    435                rtn.append( "</table>" ).append( CR );
    436
    437                return rtn.toString() ;
    438        }
    439
    440        /**
    441         * PlugIn 情報を作成します。
    442         *
    443         * @og.rev 4.0.0.0 (2005/08/31) 新規作成
    444         * @og.rev 5.6.6.0 (2013/07/05) "DBConstValue","Daemon","JspCreate" を、追加します。
    445         *
    446         * @return      PlugIn情報
    447         */
    448        private String getPlugInInfo() {
    449
    450                String[] pluginType = new String[] {
    451                                                                "Query","Renderer","Editor","DBType","ViewForm",
    452                                                                "TableReader","TableWriter","TableFilter","ChartWriter","CalendarQuery",
    453                                                                "DBConstValue","Daemon","JspCreate"                                     // 5.6.6.0 (2013/07/05) 追加
    454                                                        } ;
    455
    456                ClassInfo info = new ClassInfo();
    457
    458                for( int j=0; j<pluginType.length; j++ ) {
    459                        String type = pluginType[j] ;
    460                        HybsEntry[] names = HybsSystem.sysEntry( type + "_" );
    461                        for( int i=0; i<names.length; i++ ) {
    462                                String key              = names[i].getKey().substring( type.length()+1 );
    463                                String clsName  = names[i].getValue();
    464                                info.addLine( type,key,clsName );
    465                        }
    466                }
    467                return info.getClassInfoData() ;
    468        }
    469
    470        /**
    471         * Taglib 情報を作成します。
    472         *
    473         * @og.rev 4.0.0.0 (2006/01/31) 新規作成
    474         * @og.rev 5.3.6.0 (2011/06/01) Taglib クラス名の求め方を変更します。(jar版のみ)
    475         * @og.rev 5.5.2.6 (2012/05/25) JarFile を、Closer#zipClose( ZipFile ) メソッドを利用して、close します。
    476         *
    477         * @return      Taglib情報
    478         */
    479        private String getTaglibInfo() {
    480                ClassInfo info = new ClassInfo();
    481
    482                // 5.5.2.6 (2012/05/25) findbugs対応
    483                JarFile jarFile = null;
    484                try {
    485                        ClassLoader loader = Thread.currentThread().getContextClassLoader();
    486                        Enumeration<URL> enume = loader.getResources( "org/opengion/hayabusa/taglib/" );          // 4.3.3.6 (2008/11/15) Generics警告対応
    487                        while( enume.hasMoreElements() ) {
    488                                URL url = enume.nextElement();          // 4.3.3.6 (2008/11/15) Generics警告対応
    489                                // jar:file:/実ディレクトリ または、file:/実ディレクトリ
    490                                String dir = url.getFile();
    491                                if( "jar".equals( url.getProtocol() ) ) {
    492                                        // dir = file:/G:/webapps/gf/WEB-INF/lib/hayabusa4.0.0.jar!/org/opengion/hayabusa/taglib 形式です。
    493                                        String jar = dir.substring(dir.indexOf( ':' )+1,dir.lastIndexOf( '!' ));
    494                                        // jar = /G:/webapps/gf/WEB-INF/lib/hayabusa4.0.0.jar 形式に切り出します。
    495//                                      JarFile jarFile = new JarFile( jar );
    496                                        jarFile = new JarFile( jar );
    497                                        Enumeration<JarEntry> en = jarFile.entries() ;            // 4.3.3.6 (2008/11/15) Generics警告対応
    498                                        while( en.hasMoreElements() ) {
    499                                                JarEntry ent = en.nextElement();                // 4.3.3.6 (2008/11/15) Generics警告対応
    500                                                String file = ent.getName();
    501                                                if( ! ent.isDirectory() && file.endsWith( "Tag.class" ) ) {
    502                                                        String type             = "Taglib";
    503                                                        // 5.3.6.0 (2011/06/01) Taglib クラス名の求め方を変更します。(jar版のみ)
    504//                                                      String key              = file.substring( 0,file.length()-6 );
    505                                                        String key              = file.substring( file.lastIndexOf( '/' )+1,file.length()-6 );  // -6 は、.class 分
    506//                                                      String clsName  = "org.opengion.hayabusa.taglib." + key ;
    507                                                        String clsName  = file.replace( '/','.' ).substring( 0,file.length()-6 );
    508                                                        info.addLine( type,key,clsName );
    509                                                }
    510                                        }
    511                                        Closer.zipClose( jarFile );             // 5.5.2.6 (2012/05/25) findbugs対応
    512                                        jarFile = null;                                 // 正常終了時に、close() が２回呼ばれるのを防ぐため。
    513                                }
    514                                else {
    515                                        // dir = /G:/webapps/gf/WEB-INF/classes/org/opengion/hayabusa/taglib/ 形式です。
    516                                        File fileObj = new File( dir );
    517                                        File[] list = fileObj.listFiles();
    518                                        for( int i=0; i<list.length; i++ ) {
    519                                                String file = list[i].getName() ;
    520                                                if( list[i].isFile() && file.endsWith( "Tag.class" ) ) {
    521                                                        String type             = "Taglib";
    522                                                        String key              = file.substring( 0,file.length()-6 );
    523                                                        String clsName  = "org.opengion.hayabusa.taglib." + key ;
    524                                                        info.addLine( type,key,clsName );
    525                                                }
    526                                        }
    527                                }
    528                        }
    529                }
    530                catch( IOException ex ) {
    531                        String errMsg = "taglibファイル読み取りストリームを失敗しました。"
    532                                        + CR + ex.getMessage();
    533                        throw new RuntimeException( errMsg,ex );
    534                }
    535                finally {
    536                        Closer.zipClose( jarFile );             // 5.5.2.6 (2012/05/25) findbugs対応
    537                }
    538
    539                return info.getClassInfoData() ;
    540        }
    541
    542        /**
    543         * クラス情報を表示するためのデータを管理します。
    544         * ここでは、引数に渡された、分類(Classify)、名称(Key Name)、クラス名(Class Name)、
    545         * バージョン(Version)情報をテーブル形式で表示します。
    546         * バージョン情報は、クラス名から、インスタンスを作成して、private static final String VERSION
    547         *  フィールドの値を読み取ります。
    548         *
    549         * @og.rev 4.0.0.0 (2006/01/31) 新規作成
    550         */
    551        private static final class ClassInfo {
    552                private final StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    553                private int cnt = 0;
    554
    555                /**
    556                 * コンストラクター
    557                 *
    558                 * @og.rev 4.0.0.0 (2006/01/31) 新規作成
    559                 */
    560                public ClassInfo() {
    561                        rtn.append( "<table " ).append( TABLE_HEADER ).append( " >" ).append( CR );
    562                        rtn.append( "   <thead><tr><th>No</th><th>Classify</th><th>Key Name</th><th>Class Name</th><th>Version</th></tr></thead>" ).append( CR );
    563                        rtn.append( "   <colgroup class=\"S9\" />" ).append( CR );
    564                        rtn.append( "   <colgroup class=\"X\" />"  ).append( CR );
    565                        rtn.append( "   <colgroup class=\"X\" />"  ).append( CR );
    566                        rtn.append( "   <colgroup class=\"X\" />"  ).append( CR );
    567                        rtn.append( "   <colgroup class=\"X\" />"  ).append( CR );
    568                        rtn.append( "   <colgroup class=\"X\" />"  ).append( CR );
    569                        rtn.append( CR );
    570                }
    571
    572                /**
    573                 * テーブル表示用のデータを追加します。
    574                 *
    575                 * @og.rev 4.0.0.0 (2006/01/31) 新規作成
    576                 *
    577                 * @param       type    タイプ属性
    578                 * @param       key     キー属性
    579                 * @param       clsName クラス名(このクラス名からインスタンス化します。)
    580                 */
    581                public void addLine( final String type, final String key, final String clsName ) {
    582                        String version  = getFieldValue( clsName );
    583
    584                        boolean isCustom = ( version.compareTo( BuildNumber.VERSION_NO ) > 0 ) ||
    585                                                                version.indexOf( "Pache"   ) >= 0 ||
    586                                                                version.indexOf( "Nightly" ) >= 0 ;
    587
    588                        String trType = ( isCustom ) ? "warning" : String.valueOf( cnt%2 );
    589
    590                        rtn.append( "   <tr class=\"row_" ).append( trType ).append( "\" >" ).append( CR );
    591                        rtn.append( "           <td>" ).append( cnt++    ).append( "</td>" ).append( CR );
    592                        rtn.append( "           <td>" ).append( type     ).append( "</td>" ).append( CR );
    593                        rtn.append( "           <td>" ).append( key      ).append( "</td>" ).append( CR );
    594                        rtn.append( "           <td>" ).append( clsName  ).append( "</td>" ).append( CR );
    595                        rtn.append( "           <td>" ).append( version  ).append( "</td>" ).append( CR );
    596                        rtn.append( "   </tr>" ).append( CR );
    597                }
    598
    599                /**
    600                 * すべての内部のデータを文字列化して返します。
    601                 *
    602                 * @og.rev 4.0.0.0 (2006/01/31) 新規作成
    603                 *
    604                 * @return      作成されたテーブルデータ
    605                 */
    606                public String getClassInfoData() {
    607                        rtn.append( "</table>" ).append( CR );
    608                        return rtn.toString() ;
    609                }
    610
    611                /**
    612                 * 指定のオブジェクトの  VERSION staticフィールドの値を取得します。
    613                 *
    614                 * @og.rev 4.0.0.0 (2005/08/31) 新規作成
    615                 *
    616                 * @param       clsName 指定のクラスを表す名称
    617                 * @return      VERSION staticフィールドの値(エラー時は、そのメッセージ)
    618                 */
    619                private String getFieldValue( final String clsName ) {
    620                        String rtn ;
    621                        try {
    622                                Object obj = HybsSystem.newInstance( clsName );
    623                                Field fld = obj.getClass().getDeclaredField( "VERSION" ) ;
    624                                // privateフィールドの取得には、accessibleフラグを trueにする必要があります。
    625                                fld.setAccessible( true );
    626
    627                                rtn = (String)fld.get( null );
    628                        }
    629                        catch( Throwable ex ) {
    630                                rtn = ex.getMessage();
    631                        }
    632                        return rtn ;
    633                }
    634        }
    635
    636        /**
    637         * systemResource 情報を作成します。
    638         *
    639         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
    640         * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属性(CLS_NM)から、DBTYPEに変更
    641         *
    642         * @return      systemResource情報
    643         */
    644        private String getSystemResource() {
    645                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    646
    647                rtn.append( "<table " ).append( TABLE_HEADER ).append( " >" ).append( CR );
    648                rtn.append( "   <thead><tr><th>No</th><th>Key</th><th>Value</th></tr></thead>" ).append( CR );
    649                rtn.append( "   <colgroup class=\"S9\" />" ).append( CR );
    650                rtn.append( "   <colgroup class=\"X\" span=\"2\" />" ).append( CR );
    651                rtn.append( CR );
    652
    653                String[][] str = HybsSystem.getSystemResourceData();
    654                for( int i=0; i<str[0].length; i++ ) {
    655                        rtn.append( "   <tr class=\"row_" ).append( i%2 ).append( "\" >" ).append( CR );
    656                        rtn.append( "           <td>" ).append( String.valueOf( i+1 ) ).append( "</td>" ).append( CR );
    657                        rtn.append( "           <td>" ).append( str[0][i] ).append( "</td>" ).append( CR );
    658                        rtn.append( "           <td>" ).append( str[1][i] ).append( "</td>" ).append( CR );
    659                        rtn.append( "   </tr>" ).append( CR );
    660                }
    661                rtn.append( "</table>" ).append( CR );
    662
    663                return rtn.toString();
    664        }
    665
    666        /**
    667         * AccessStop 情報を作成します。
    668         *
    669         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
    670         * @og.rev 4.0.0.0 (2007/11/29) AccessStopFilter#getStopFilter() ⇒ isStopFilter() に変更
    671         *
    672         * @return      AccessStop情報
    673         */
    674        private String getAccessStop() {
    675
    676//              boolean flag = org.opengion.hayabusa.filter.AccessStopFilter.getStopFilter();
    677                boolean flag = org.opengion.hayabusa.filter.AccessStopFilter.isStopFilter();
    678                flag = !flag ;
    679
    680                final String rtn ;
    681                if( flag ) {
    682                        rtn = "Webアプリケーションのサービスを停止します。";
    683                }
    684                else {
    685                        rtn = "Webアプリケーションのサービスを開始します。";
    686                }
    687                org.opengion.hayabusa.filter.AccessStopFilter.setStopFilter( flag );
    688
    689                return rtn ;
    690        }
    691
    692        /**
    693         * admin リンク情報を作成します。
    694         * 簡易メソッドなので、国際化対応していません。
    695         *
    696         * @og.rev 3.5.4.1 (2003/12/01) 新規作成
    697         * @og.rev 5.1.1.2 (2009/12/10) 画面IDを変更
    698         * @og.rev 5.6.3.4 (2013/04/26) ｸｲｯｸﾘﾌｧﾚﾝｽ 画面を追加
    699         *
    700         * @return      アドミンリンク情報
    701         */
    702        private String getAdminLink() {
    703                StringBuilder rtn = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
    704
    705                rtn.append( "<table><tr>" ).append( CR );
    706                rtn.append( "<td width=\"10px\"/>" ).append( CR );
    707                rtn.append( "<td>[<a href=\"admin?COMMAND=infomation\" target=\"RESULT\" >状況表示</a>]</td>" ).append( CR );
    708                rtn.append( "<td width=\"10px\"/>" ).append( CR );
    709                rtn.append( "<td>[<a href=\"admin?COMMAND=close\" target=\"RESULT\" >ﾌﾟｰﾙ削除</a>]</td>" ).append( CR );
    710                rtn.append( "<td width=\"10px\"/><td>" ).append( CR );
    711                rtn.append( "[<a href=\"admin?COMMAND=loginUser\" target=\"RESULT\" >ﾛｸﾞｲﾝﾕｰｻﾞｰ</a>]</td>" ).append( CR );
    712                rtn.append( "<td width=\"10px\"/><td>" ).append( CR );
    713                rtn.append( "[<a href=\"admin?COMMAND=plugin\" target=\"RESULT\" >ﾌﾟﾗｸﾞｲﾝ情報</a>]</td>" ).append( CR );
    714                rtn.append( "<td width=\"10px\"/><td>" ).append( CR );
    715                rtn.append( "[<a href=\"admin?COMMAND=taglib\" target=\"RESULT\" >ﾀｸﾞﾘﾌﾞ情報</a>]</td>" ).append( CR );
    716                rtn.append( "<td width=\"10px\"/><td>" ).append( CR );
    717                rtn.append( "[<a href=\"common/quickReference.html\" target=\"RESULT\" >ｸｲｯｸﾘﾌｧﾚﾝｽ</a>]</td>" ).append( CR ); // 5.6.3.4 (2013/04/26)
    718                rtn.append( "<td width=\"10px\"/><td>" ).append( CR );
    719                rtn.append( "[<a href=\"admin?COMMAND=systemResource\" target=\"RESULT\" >ｼｽﾃﾑﾘｿｰｽ</a>]</td>" ).append( CR );
    720                rtn.append( "<td width=\"10px\"/><td>" ).append( CR );
    721//              rtn.append( "[<a href=\"common/gamen/01_ADMIN/parameter.jsp?GAMENID=ADMIN\" target=\"RESULT\" >Parameter</a>]</td>" ).append( CR );
    722                rtn.append( "[<a href=\"common/gamen/01_ADMIN/parameter.jsp?GAMENID=01_ADMIN\" target=\"RESULT\" >Parameter</a>]</td>" ).append( CR );
    723                rtn.append( "</tr></table>" ).append( CR );
    724
    725                return rtn.toString();
    726        }
    727
    728        /**
    729         * DBTableModel から テーブルのタグ文字列を作成して返します。
    730         *
    731         * @og.rev 3.5.3.1 (2003/10/31) User情報のテーブルの設定を、システムリソース より行う。
    732         * @og.rev 5.2.2.0 (2010/11/01) SystemData 見直し漏れの対応。
    733         *
    734         * @return      テーブルのタグ文字列
    735         */
    736        private static String getTableHeaderTag() {
    737                Attributes attri = new Attributes();
    738                attri.set( "id" ,"viewTable" );         // 3.6.0.5 (2004/10/18)
    739                attri.set( "summary"     ,"layout"        );                    // サマリー
    740
    741//              // 4.0.0 (2005/08/31) テーブル表示の CSSファイル利用の有無
    742//              boolean useCSSfile = HybsSystem.sysBool( "USE_HTML_TABLE_CSS" ) ;
    743//
    744//              if( ! useCSSfile ) {
    745//                      attri.set( "summary"     ,"layout"        );                    // サマリー
    746//                      attri.set( "border"      ,HybsSystem.sys( "HTML_BORDER" ) ) ;     // 外枠の太さ
    747//                      attri.set( "width"               ,HybsSystem.sys( "HTML_WIDTH" )  ) ;     // 表の大きさ(幅)ピクセルまたは,％
    748//                      attri.set( "frame"               ,HybsSystem.sys( "HTML_FRAME" )  ) ;     // 外枠の表示形式  void,above,below,lhs,rhs,hsides,vsides,box,border
    749//                      attri.set( "rules"               ,HybsSystem.sys( "HTML_RULES" )  ) ;     // セルを区切る線の形式 none,rows,cols,groups,all
    750//                      attri.set( "cellspacing" ,HybsSystem.sys( "HTML_CELLSPACING" ) );  // セルの間隔
    751//                      attri.set( "cellpadding" ,HybsSystem.sys( "HTML_CELLPADDING" ) );  // セル内のマージン
    752//              }
    753
    754                return attri.getAttribute();
    755        }
    756}