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