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 org.opengion.fukurou.system.OgRuntimeException;                                                  // 6.4.2.0 (2016/01/29)
019import java.io.File;
020import java.io.IOException;
021import java.io.PrintWriter;
022import java.lang.reflect.Field;
023import java.net.URL;
024import java.util.Enumeration;
025import java.util.Map;
026import java.util.concurrent.ConcurrentMap;                                                                              // 6.4.3.3 (2016/03/04)
027import java.util.jar.JarEntry;
028import java.util.jar.JarFile;
029
030import jakarta.servlet.ServletContext;
031import jakarta.servlet.ServletException;
032import jakarta.servlet.http.HttpServlet;
033import jakarta.servlet.http.HttpServletRequest;
034import jakarta.servlet.http.HttpServletResponse;
035import jakarta.servlet.http.HttpSession;
036
037import org.opengion.fukurou.db.ConnectionFactory;
038import org.opengion.fukurou.util.Attributes;
039import org.opengion.fukurou.util.HybsEntry;
040import org.opengion.fukurou.util.StringUtil;
041import org.opengion.fukurou.fileexec.MainProcess;                                                               // 7.2.5.0 (2020/06/01)
042import org.opengion.fukurou.system.BuildNumber;                                                                 // 6.4.2.0 (2016/01/29) hayabusa.common.BuildNumber → fukurou.system.BuildNumber に移動
043import org.opengion.fukurou.system.Closer ;                                                                             // 5.5.2.6 (2012/05/25)
044import org.opengion.hayabusa.common.HybsSystem;
045import org.opengion.hayabusa.common.SystemManager;
046import org.opengion.hayabusa.common.SystemParameter;
047import org.opengion.hayabusa.common.UserSummary;
048import static org.opengion.fukurou.system.HybsConst.CR ;                                                // 6.1.0.0 (2014/12/26)
049import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;                              // 6.1.0.0 (2014/12/26) refactoring
050
051import org.opengion.hayabusa.resource.ResourceFactory;                                                  // 5.9.1.0 (2015/10/02)
052import org.opengion.hayabusa.resource.UserInfo;                                                                 // 5.9.1.0 (2015/10/02)
053
054import jakarta.servlet.ServletRegistration;                                                                             // 6.3.4.0 (2015/08/01)
055import jakarta.servlet.FilterRegistration;                                                                              // 6.3.4.0 (2015/08/01)
056import jakarta.servlet.annotation.WebServlet;                                                                           // 7.3.0.0 (2021/01/06)
057
058/**
059 * サーバー管理情報を取得するAdminサーブレットです。
060 *
061 * 引数(URL)に応じて、サーバーの状態結果を返します。
062 * 一般には、http://サーバー:ポート/システムID/jsp/admin?COMMAND=コマンド の
063 * 形式のURL でアクセスします。
064 *
065 *  ・COMMAND=infomation
066 *     【サーバー情報】
067 *        OS情報      = Windows 7 Service Pack 1 x86 (32)
068 *        サーバー名    = 10374232-0004 ( 172.27.26.164 )
069 *        サーブレット  = Apache Tomcat/8.0.22
070 *        TOMCAT_HOME   = C:\opengionV6\apps\tomcat8.0.22
071 *        JDKバージョン = Java HotSpot(TM) Server VM 1.8.0_45-b15
072 *        JAVA_HOME     = C:\opengionV6\apps\jdk180u45\jre
073 *     【実行環境】
074 *        REAL_PATH     = C:/opengionV6/uap/webapps/gf/
075 *        バージョンNo  = openGion 6.2.4.0 Release6 Builds (2015142)
076 *        作成日時      = 2015/05/22 15:31:53
077 *     【ログイン情報】
078 *        ログイン人数  = 2 名 ( 明細情報 )
079 *     【メモリ情報】
080 *        空きメモリ    = 129 [MByte]
081 *        合計メモリ    = 209 [MByte]
082 *        使用率        = 38 [%]
083 *     【ディスク情報】
084 *
085 *  ・COMMAND=close
086 *       リソース情報のキャッシュを全てクリアします。
087 *
088 *  ・COMMAND=loginUser
089 *       現在のログインユーザーの明細情報を表示します。
090 *       SORT=[JNAME,ID,ROLES,IPADDRESS,LOGINTIME] ソートキー
091 *       DIREC=[true,false] true:昇順/false:降順
092 *  ・COMMAND=systemResource
093 *       現在のシステムリソースの設定情報を表示します。
094 *
095 *  ・COMMAND=AccessStop&stop=[true/false]
096 *       アクセスストップフィルターの制御(停止、許可)を行います。
097 *  ・common/gamen/01_ADMIN/parameter.jsp
098 *       現在のシステムリソースの設定情報を表示します。
099 *
100 *  ・common/gamen/01_ADMIN/systemInfo.jsp
101 *       システム定数のシステム起動情報を表示します。
102 *
103 *    ※ 7.1.0.0 (2020/01/20)
104 *  ・common/gamen/01_ADMIN/logLink.jsp
105 *       Tomcatのlogを表示します。
106 *
107 *    ※ 7.1.0.0 (2020/01/20)
108 *  ・common/gamen/01_ADMIN/serviceRestart.jsp
109 *       Tomcatのサービスを再起動(停止―開始)します。
110 *
111 * @og.rev 3.5.3.0 (2003/10/27) Admin JSP を Servlet化して、エンジンと共に供給します。
112 * @og.rev 4.0.0.0 (2005/08/31) プラグインのバージョン情報の表示機能を追加
113 * @og.group その他機能
114 *
115 * @version  4.0
116 * @author   Kazuhiko Hasegawa
117 * @since    JDK5.0,
118 */
119@WebServlet( "/jsp/admin" )
120public final class HybsAdmin extends HttpServlet {
121        private static final long serialVersionUID = 624120150522L ;                            // 6.2.4.1 (2015/05/22)
122
123        private static final String JSP = HybsSystem.sys( "JSP" );                                      // jspフォルダの正規パス
124
125        private static final long MB = 1024*1024 ;                                                                      // 6.2.4.1 (2015/05/22)
126        private static final long GB = 1024*1024*1024 ;                                                         // 6.2.4.1 (2015/05/22)
127
128        // 7.0.1.0 (2018/10/15) XHTML → HTML5 対応
129        // 8.1.0.0 (2021/12/28) HTML5 準拠に見直し
130//      private static final String HEADER =
131//              "<!DOCTYPE html>"                                                                                                                                                       + CR +
132//              "<html class=\"headtype-query\">"                                                                                                                       + CR +
133//              "<head>"                                                                                                                                                                        + CR +
134//              "       <meta charset=\"UTF-8\" >"                                                                                                                              + CR +
135//              "       <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" >"                                                             + CR +
136//              "       <link rel=\"stylesheet\" href=\"" + JSP + "/common/default.css\" type=\"text/css\" >"   + CR +
137//              "       <link rel=\"stylesheet\" href=\"" + JSP + "/custom/custom.css\" type=\"text/css\" >"    + CR +
138//              "       <title>Hybs Admin</title>"                                                                                                                              + CR +
139//              "</head>"                                                                                                                                                                       + CR;
140
141        // 8.1.0.0 (2021/12/28) HTML5 準拠に見直し(lang="ja",content="IE=edge" 不要,type="text/css" 不要)
142        private static final String HEADER =
143                "<!DOCTYPE html>"                                                                                                               + CR +
144                "<html lang=\"ja\" class=\"headtype-query\">"                                                   + CR +
145                "<head>"                                                                                                                                + CR +
146                "       <meta charset=\"UTF-8\" >"                                                                                      + CR +
147                "       <link rel=\"stylesheet\" href=\"" + JSP + "/common/default.css\" >"     + CR +
148                "       <link rel=\"stylesheet\" href=\"" + JSP + "/custom/custom.css\" >"      + CR +
149                "       <title>Hybs Admin</title>"                                                                                      + CR +
150                "</head>"                                                                                                                               + CR;
151
152        // 3.5.3.1 (2003/10/31) User情報のテーブルの設定を、システムリソース より行う。
153        private static final String TABLE_HEADER = getTableHeaderTag() ;
154
155        // 5.6.6.0 (2013/07/05) getLoginUser( String,boolean ) で、指定するキーを配列で持っておきます。
156        // キーは、SystemManager.getRunningUserSummary 処理内で大文字化されるため、この配列は、表示用と兼用します。
157        private static final String[] USER_KEYS = { "ID","Jname","Roles","IPAddress","LoginTime","LastAccess","LastGamenNm" };
158
159        // 6.3.6.1 (2015/08/28) <table> 枠の指定と、</table> の static final String 化
160        private static final String TABLE_WAKU  = "<table style=\"margin: 0px 0px 0px 20px;\" frame=\"box\" border=\"1px\" cellspacing=\"0px\" cellpadding=\"0px\" " ;
161        private static final String TABLE_END   = "</table>" + CR ;
162
163        // 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
164        private static final String COMMON_MESSAGE =
165                        "【共通メッセージを表示する場合は、このテキストフィールドに入力してください。】<br>"   + CR +
166                        "<form method=\"GET\" action=\"" + JSP + "/admin\" target=\"RESULT\" >"                                 + CR +
167                        "    <input name=\"message\" size=\"50\" >"                                                                                             + CR +
168                        "    <button type=\"submit\" name=\"type\" value=\"set\"   >Set</button>"                               + CR +
169                        "    <button type=\"submit\" name=\"type\" value=\"clear\" >Clear</button>"                             + CR +
170                        "    <input type=\"hidden\" name=\"COMMAND\" value=\"commonMessage\" >"                                 + CR +
171                        "</form><br><br>"                                                                                                                                               + CR ;
172
173        // 7.1.0.0 (2020/01/27) static で定義しておきます。
174        private static final String[] PLUGIN_TYPE = new String[] {
175                                "Query","Renderer","Editor","DBType","ViewForm",
176                                "TableReader","TableWriter","TableFilter","ChartWriter","CalendarQuery",
177                                "DBConstValue","Daemon","JspCreate"                                                             // 5.6.6.0 (2013/07/05) 追加
178        } ;
179
180        // 7.1.0.0 (2020/01/27) static で定義しておきます。
181        private static final String TD_CMD = "  <td>  [<a href=\"" + JSP + "/admin?COMMAND=" ;
182        private static final String TD_QREF= "  <td>  [<a href=\"" + JSP + "/common/quickReference.html" ;              // クイックリファレンス 専用
183        private static final String TD_GMN = "  <td>  [<a href=\"" + JSP + "/common/gamen/01_ADMIN/" ;
184        private static final String YESNO  = "\" onclick=\"return confirm( '実行してよろしいでしょうか?' );" ;
185        private static final String TGT    = "\" target=\"RESULT\" >" ;
186        private static final String END_TD = "</a>]</td>" + CR ;
187
188        private static final String INFOMATION          = TD_CMD + "infomation"                 + TGT + "状況表示"                  + END_TD ;
189        private static final String CLOSE                       = TD_CMD + "close"                              + TGT + "プール削除"                        + END_TD ;
190        private static final String LOGIN_USER          = TD_CMD + "loginUser"                  + TGT + "ログインユーザー"            + END_TD ;
191        private static final String QUICK_REFERENCE     = TD_QREF                                               + TGT + "クイックリファレンス"            + END_TD ;
192        private static final String SYSTEM_RESOURCE     = TD_CMD + "systemResource"             + TGT + "システムリソース"                      + END_TD ;
193        private static final String PARAMETER           = TD_GMN + "parameter.jsp?GAMENID=01_ADMIN" + TGT + "パラメータ"+ END_TD ;
194        private static final String LOGLINK                     = TD_GMN + "logLink.jsp"                + TGT + "ログ"                           + END_TD ;
195        private static final String SERVICE_RESTART     = TD_GMN + "serviceRestart.jsp" + YESNO + TGT + "サービス再起動" + END_TD ;
196
197        private static final String PLUGIN                      = TD_CMD + "plugin"                             + TGT + "プラグイン情報"             + END_TD ;
198        private static final String TAGLIB                      = TD_CMD + "taglib"                             + TGT + "タグリブ情報"              + END_TD ;
199        private static final String REGISTRATION        = TD_CMD + "registrationInfo"   + TGT + "Servlet/Filter"        + END_TD ;
200        private static final String SYSTEM_INFO         = TD_GMN + "systemInfo.jsp"             + TGT + "システム状況"                        + END_TD ;
201        private static final String ACCESS_STOP         = "<td colspan=\"2\">  アクセス制限"
202                                                                                                                + "[<a href=\"" + JSP + "/admin?COMMAND=AccessStop&stop=true"   + TGT + "停止</a>]/"
203                                                                                                                + "[<a href=\"" + JSP + "/admin?COMMAND=AccessStop&stop=false"  + TGT + "開始" + END_TD ;
204
205        // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
206        private static final String TD_TD = "</td><td>" ;                       // tdの終了とtdの開始を連結したもの
207        private static final String TD_TR = "</td></tr>" + CR ;         // tdの終了とtrの終了を連結したもの
208
209        /**
210         * fileexecのMainProcess の処理が起動しているかどうかを表示。
211         *
212         * @og.rev 7.2.5.0 (2020/06/01) fileexecのMainProcess の処理が起動しているかどうかを表示
213         *
214         * @return      fileexecの起動情報
215         * @og.rtnNotNull
216         */
217        public static String fileExecCmnt() {
218                final boolean isStart = MainProcess.isStarted();
219                return "ファイル取込(" + ( isStart ? "起動中" : "停止中" ) + ")  " ;
220
221//              return "<td colspan=\"2\">  ファイル取込("
222//                                      + ( isStart ? "起動中" : "停止中" ) + ") "
223//                                      + "[<a href=\"" + JSP + "/admin?COMMAND=fileexec&start=" + !isStart + TGT               // 他の admin もJSP が必要なはず。
224//                                      + "<b>" + ( isStart ? "待機する" : "実行する" )  + "</b>" + END_TD
225//                                      + "<td>  起動するには、システム定数で、パラメータID=USE_FILEEXEC を、true に登録してください。(要[プール削除])</td>" ;
226        }
227
228        /**
229         * GET メソッドが呼ばれたときに実行します。
230         *
231         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
232         * @og.rev 3.5.4.1 (2003/12/01) getAdminLink() メソッドを追加
233         * @og.rev 6.3.8.0 (2015/09/11) AccessStop を外部から制御できるように、コマンドと状態を受けるようにする。
234         * @og.rev 5.9.1.0 (2015/10/02) UserInfoセット機能追加
235         * @og.rev 6.3.8.3 (2015/10/03) Servlet/Filter 情報を作成。
236         * @og.rev 6.3.9.1 (2015/11/27) 3項演算子を || or &amp;&amp; で簡素化できる(PMD)。
237         * @og.rev 6.4.4.1 (2016/03/18) application オブジェクトに関連付ける 共通メッセージを設定します。
238//       * @og.rev 7.2.5.0 (2020/06/01) fileexecのMainProcess の処理が起動しているかどうかを表示
239         *
240         * @param       req     HttpServletRequestオブジェクト
241         * @param       res     HttpServletResponseオブジェクト
242         *
243         * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
244         * @throws IOException 入出力エラーが発生したとき
245         */
246        @Override
247        public void doGet( final HttpServletRequest req, final HttpServletResponse res)
248                                                                throws ServletException, IOException {
249
250                req.setCharacterEncoding( "UTF-8" );                                                            // 6.4.4.1 (2016/03/18)
251                res.setContentType( "text/html; charset=UTF-8" );
252                final PrintWriter out = res.getWriter();
253
254                final String command = req.getParameter( "COMMAND" );
255
256                out.println( HEADER );
257                out.println( "<body>" );
258
259//              out.print("<h2>");
260                out.print("<div style=\"font-size:1.5em;\">");
261                out.print( req.getServerName() );
262                out.print( ":" );
263                out.print( req.getServerPort() );
264                out.print( req.getContextPath() );
265//              out.println("</h2>");
266                out.println("</div>");
267
268                if( "infomation".equalsIgnoreCase( command ) ) {
269                        out.print( getInfomation() );
270                }
271                else if( "close".equalsIgnoreCase( command ) ) {
272                        out.print( getCloseMessage( req.getSession() ) );
273                }
274                else if( "loginUser".equalsIgnoreCase( command ) ) {
275                        final String sort  = req.getParameter( "sort" );
276                        final String direc = req.getParameter( "direc" );
277                        // 6.3.9.1 (2015/11/27) 3項演算子を || or && で簡素化できる(PMD)。
278                        final boolean dir = direc == null || Boolean.parseBoolean( direc );     // 6.3.9.1 (2015/11/27)
279
280                        out.print( COMMON_MESSAGE );                                                                            // 6.4.4.1 (2016/03/18)
281                        out.print( getLoginUser(sort,dir) );
282                }
283                // 6.4.4.1 (2016/03/18) application オブジェクトに関連付ける 共通メッセージを設定します。
284                else if( "commonMessage".equalsIgnoreCase( command ) ) {
285                        final String type    = req.getParameter( "type" );
286                        final String message = req.getParameter( "message" );
287                        out.print( setCommonMessage( type , message , req.getSession() ) );
288                }
289                else if( "plugin".equalsIgnoreCase( command ) ) {
290                        out.print( getPlugInInfo() );
291                }
292                else if( "taglib".equalsIgnoreCase( command ) ) {
293                        out.print( getTaglibInfo() );
294                }
295                else if( "systemResource".equalsIgnoreCase( command ) ) {
296                        out.print( getSystemResource() );
297                }
298                // 6.3.8.0 (2015/09/11) AccessStop を外部から制御できるように、コマンドと状態を受けるようにする。
299                else if( "AccessStop".equalsIgnoreCase( command ) ) {
300                        out.print( getAccessStop( req.getParameter( "stop" ) ) );                       // 6.3.8.0 (2015/09/11)
301                }
302                // 5.9.1.0 (2015/10/02) UserInfoセット機能追加
303                else if( "UserInfo".equalsIgnoreCase( command ) ){ // 5.9.1.0 (2015/10/02)
304                        out.print( setUserinfo( req ) );
305                }
306                // 6.3.8.3 (2015/10/03) Servlet/Filter 情報を作成。
307                else if( "registrationInfo".equalsIgnoreCase( command ) ) {
308                        out.print( getRegistrationMessage( req.getSession() ) );
309                }
310//              else if( "fileexec".equalsIgnoreCase( command ) ) {             // 7.2.5.0 (2020/06/01)
311//                      out.print( getFileExecInfo( req.getParameter( "start" ) ) );
312//              }
313                else {
314                        out.print( getAdminLink() );                                                                            // 3.5.4.1 (2003/12/01) 追加
315                }
316
317                out.println("</body></html>");
318        }
319
320        /**
321         * infomation 情報を作成します。
322         *
323         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
324         * @og.rev 5.6.7.3 (2013/08/23) TOMCAT_WORKは、TOMCAT_HOME に置き換えます。
325         * @og.rev 6.2.4.1 (2015/05/22) ディスク容量を求めます。
326         * @og.rev 6.3.6.1 (2015/08/28) <table> 枠の指定と、</table> の static final String 化
327         * @og.rev 6.3.9.0 (2015/11/06) 整数値演算なので、Math.round 不要
328         * @og.rev 6.5.0.1 (2016/10/21) ENGINE_INFO は、直接、BuildNumber から取得する。
329         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
330         * @og.rev 7.1.0.0 (2020/01/20) OFFICE_HOME,EXT_DIR,SYS_LOG_URL,LOGS_DIR 環境変数の追加。
331         *
332         * @return      infomation情報
333         * @og.rtnNotNull
334         */
335        private String getInfomation() {
336                // 4.0.0 (2005/01/31) ログイン数の取得方法の変更。
337                final int loginCount = SystemManager.getRunningCount() ;
338
339                final long freeMemory     = Runtime.getRuntime().freeMemory()/MB ;              // 6.3.9.0 (2015/11/06) 整数値演算なので、Math.round 不要
340                final long totalMemory    = Runtime.getRuntime().totalMemory()/MB;              // 6.3.9.0 (2015/11/06) 整数値演算なので、Math.round 不要
341                final long useMemoryRatio = (totalMemory-freeMemory)*100/totalMemory ;  // 6.3.9.0 (2015/11/06) 整数値演算なので、Math.round 不要
342                final String bgCls = useMemoryRatio <= 50 ? "OK" : useMemoryRatio <= 80 ? "CAUT" : "NG" ;       // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
343
344                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
345
346                rtn.append( "<table border = \"0px\" >" );
347//              // 7.1.0.0 (2020/01/20) static定義をやめて、getInfomation() メソッド内で都度呼びます。
348                tableTr1( rtn,"サーバー情報" );
349                tableTr(  rtn,"OS情報"                    , BuildNumber.OS_INFO );                                // 6.5.0.1 (2016/10/21)
350                tableTr(  rtn,"サーバー名"                  , HybsSystem.sys( "SERVER_INFO"  ) );   // 10759278-0002
351                tableTr(  rtn,"サーブレット"                 , HybsSystem.sys( "SERVLET_INFO" ) );   // Apache Tomcat/X.X.XX
352                tableTr(  rtn,"TOMCAT_HOME"             , HybsSystem.sys( "TOMCAT_HOME"  ) );   // /apps/tomcatX.X.XX
353                tableTr(  rtn,"  ログフォルダ"      , HybsSystem.sys( "TOMCAT_LOGS"  ) );   // /apps/tomcatX.X.XX/logs
354                tableTr(  rtn,"JDKバージョン"              , BuildNumber.JDK_INFO             );   // OpenJDK 64-Bit Server VM 11.0.5+10-LTS
355                tableTr(  rtn,"JAVA_HOME"               , HybsSystem.sys( "JAVA_HOME"    ) );   // apps/jdkX.X.X
356                tableTr(  rtn,"  拡張フォルダ"       , HybsSystem.sys( "EXT_DIR"      ) );   // /uap/bin/../../apps/endorsedX.X.X
357                tableTr(  rtn,"OFFICE_HOME"             , HybsSystem.sys( "OFFICE_HOME"  ) );   // /uap/bin/../../apps/LibreOffice_X.X.X
358
359//              // 7.1.0.0 (2020/01/20) static定義をやめて、getInfomation() メソッド内で都度呼びます。
360                tableTr1( rtn,"実行環境" );
361                tableTr(  rtn,"サービス起動"         , HybsSystem.sys( "IS_SERVICE"   ) , " [ " , HybsSystem.sys( "SERVICE_NAME" ) , " ] " );        // true [ サービス名 ]
362                tableTr(  rtn,"REAL_PATH"               , HybsSystem.sys( "REAL_PATH"    ) );   // /uap/webapps/gf/
363                tableTr(  rtn,"バージョンNo"               , BuildNumber.ENGINE_INFO          );   // 7.1.0.0 Release7 Builds (26324783)
364                tableTr(  rtn,"作成日時"            , BuildNumber.TIMESTAMP            );   // 2020/01/20 11:23:37
365
366                tableTr1( rtn,"ログイン情報" );
367                tableTr(  rtn,"ログイン人数"         , String.valueOf( loginCount )," 名 ","( <a href=\"admin?COMMAND=loginUser\">明細情報</a> )" );
368
369                tableTr1( rtn,"メモリ情報" );
370                tableTr(  rtn,"空きメモリ"                   , String.valueOf( freeMemory     ) , " [MByte]" );      // 6.2.4.1 (2015/05/22) 単位を MB に変更
371                tableTr(  rtn,"合計メモリ"                   , String.valueOf( totalMemory    ) , " [MByte]" );      // 6.2.4.1 (2015/05/22) 単位を MB に変更
372                tableTr(  rtn,"使用率"                     , String.valueOf( useMemoryRatio ) , " [%]"    );
373                rtn.append( TABLE_END )
374                        // 6.2.4.1 (2015/05/22) default.css で、memory、disc、discTD を定義
375                        .append( TABLE_WAKU ).append( "width=\"300px\" >" ).append( CR )
376                        .append( "\t<tr><td class=\"memory " ).append( bgCls ).append( "\" style=\"width:" )
377                        .append( useMemoryRatio ).append( "%;\" >" ).append( useMemoryRatio ).append( "%</td>" )
378                        .append( "<td class=\"BIT\">" ).append( 100-useMemoryRatio ).append( "%</td></tr>" ).append( CR )
379                        .append( TABLE_END )
380
381                        // 6.2.4.1 (2015/05/22) ディスク容量を求めます。
382                        .append( "<table border=\"0px\" >" ).append( CR );
383                tableTr1( rtn,"ディスク情報" );
384                rtn.append( TABLE_END )
385                        .append( TABLE_WAKU ).append( "width=\"500px\" >" ).append( CR )
386                        .append( "<th>名前</th><th>合計サイズ</th><th>空き領域</th><th>使用率</th></tr>" ).append( CR ).append( CR );
387
388                final File[] driv = File.listRoots();
389                for( final File file : driv ) {
390                        // 6.3.9.0 (2015/11/06) 整数値演算なので、Math.round 不要
391                        final long total        = file.getTotalSpace()/GB ;                                             // パーティションのサイズ
392                        final long usable       = file.getUsableSpace()/GB ;                                    // 仮想マシンが利用できるバイト数
393                        tableTr2( rtn, file.getPath() , total , usable );                                       // ディスク容量専用3
394                }
395                rtn.append( TABLE_END )
396
397                // information
398                        .append( "<hr>" ).append( CR )                                                                          // 7.0.1.0 (2018/10/15) XHTML → HTML5
399                        .append( "<pre>" ).append( CR )
400                        .append( ConnectionFactory.information() ).append( CR )
401                        .append( "</pre>" ).append( CR );
402
403                return rtn.toString();
404        }
405
406        /**
407         * infomation 情報を作成します。
408         *
409         * @og.rev 5.6.6.0 (2013/07/05) &lt;/td&gt;&lt;/tr&gt;漏れ追加
410         * @og.rev 5.6.7.3 (2013/08/23) 前後に、【】を付けます。
411         *
412         * @param       buf     情報登録用のStringBuilder
413         * @param       key     キー
414         *
415         * @return      infomation情報(入力bufと同じオブジェクト)
416         * @og.rtnNotNull
417         */
418        private StringBuilder tableTr1( final StringBuilder buf, final String key ) {
419                return buf.append( "\t<tr><td colspan=\"4\"><b>【" )
420                                .append( key ).append( "】</b></td></tr>" )
421                                .append( CR );  // 【】追加
422        }
423
424        /**
425         * infomation 情報を作成します。
426         *
427         * @og.rev 5.6.6.0 (2013/07/05) 最初の td に、全角スペース2個 追加
428         *
429         * @param       buf     情報登録用のStringBuilder
430         * @param       key     キー
431         * @param       val     値の可変長引数
432         *
433         * @return      infomation情報(入力bufと同じオブジェクト)
434         * @og.rtnNotNull
435         */
436        private StringBuilder tableTr( final StringBuilder buf, final String key, final String... val ) {
437                buf.append( "\t<tr><td width=\"20px\"> </td><td>" ).append( key ).append( "</td><td> = </td><td>" );    // 段を作成する為に、width指定 追加
438                for( int i=0; i<val.length; i++ ) {
439                        buf.append( val[i] );
440                }
441//              return buf.append( "</td></tr>" ).append( CR );
442                return buf.append( TD_TR );
443        }
444
445        /**
446         * infomation 情報を作成します。
447         *
448         * @og.rev 6.2.4.1 (2015/05/22) ディスク容量専用
449         * @og.rev 6.2.4.2 (2015/05/29) total が 0 の場合の対応
450         * @og.rev 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
451         *
452         * @param       buf     情報登録用のStringBuilder
453         * @param       name    ドライブ名
454         * @param       total   パーティションのサイズ(GB)
455         * @param       usable  仮想マシンが利用できるサイズ(GB)
456         *
457         * @return      infomation情報(入力bufと同じオブジェクト)
458         * @og.rtnNotNull
459         */
460        private StringBuilder tableTr2( final StringBuilder buf, final String name, final long total, final long usable ) {
461                final long useRatio = total == 0L ? 0L : (total-usable)*100/total ;             // 6.3.9.0 (2015/11/06) findBugs
462
463                final String bgCls = useRatio <= 50 ? "OK" : useRatio <= 80 ? "CAUT" : useRatio <= 95 ? "WARN" : "NG" ; // 6.9.7.0 (2018/05/14) PMD Useless parentheses.
464
465//              return buf.append( "\t<tr><td class=\"BIT\">" ).append( name ).append( "</td>" )
466//                      .append( "<td class=\"S9\" >" ).append( total  ).append( " GB</td>" )
467//                      .append( "<td class=\"S9\" >" ).append( usable ).append( " GB</td>" ).append( CR )
468//                      .append( "\t\t<td class=\"discTD\" ><span class=\"disc " ).append( bgCls )
469//                      .append( "\" style=\"width:" ).append( useRatio ).append( "%;\" >" )
470//                      .append( useRatio ).append( "%</span> </td></tr>" ).append( CR );
471
472                // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
473                return buf.append( "\t<tr><td class=\"BIT\">"   )
474                        .append( name           ).append( "</td><td class=\"S9\" >" )
475                        .append( total          ).append( " GB</td><td class=\"S9\" >" )
476                        .append( usable         ).append( " GB</td>" ).append( CR )
477                        .append( "\t\t<td class=\"discTD\" ><span class=\"disc " )
478                        .append( bgCls          ).append( "\" style=\"width:" )
479                        .append( useRatio       ).append( "%;\" >" )
480                        .append( useRatio       ).append( "%</span> </td></tr>" ).append( CR );
481        }
482
483        /**
484         * close 情報を作成します。
485         *
486         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
487         * @og.rev 3.6.0.0 (2004/09/17) CalendarFactory.clear() を追加します。
488         * @og.rev 4.0.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
489         * @og.rev 4.1.0.2 (2008/01/29) UserInfoをsessionから消去する(超暫定対応)
490         * @og.rev 5.6.6.0 (2013/07/05) UserSummary の削除処理は、SystemManager から行う。
491         * @og.rev 6.3.7.0 (2015/09/04) ファイナライズを呼び出します。
492         * @og.rev 7.2.9.4 (2020/11/20) PMD:Do not explicitly trigger a garbage collection.
493         *
494         * @param       session HttpSessionオブジェクト
495         *
496         * @return      close情報
497         * @og.rtnNotNull
498         */
499        private String getCloseMessage( final HttpSession session ) {
500
501                // 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
502                SystemManager.allClear( false ) ;
503
504                final ServletContext context = session.getServletContext();
505                final Map<String,String> param = SystemParameter.makeSystemParameter( context );
506                HybsSystem.setInitialData( param );                     // 4.0.0 (2005/01/31)
507
508                // 5.6.6.0 (2013/07/05) UserSummary の削除処理は、SystemManager から行う。
509                SystemManager.removeSession( session ) ;
510
511                // 6.3.7.0 (2015/09/04) ファイナライズを呼び出します。
512                // 7.2.9.4 (2020/11/20) PMD:Do not explicitly trigger a garbage collection.
513//              System.runFinalization();
514//      //      System.gc();                                    // 取りあえず、GCは呼びません。
515
516                return "<pre>"
517                        + "キャッシュ情報をクリアしました。"                                                                                    + CR
518                        + "ユーザー情報の初期化に関しては、ブラウザを閉じて、再ログインが必要です。"        + CR
519                        + ConnectionFactory.information()
520                        + "</pre>" ;
521        }
522
523        /**
524         * loginUser 情報を作成します。
525         *
526         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
527         * @og.rev 3.8.5.3 (2006/08/07) ユーザー情報をソートするためのキー情報を追加
528         * @og.rev 3.8.7.0 (2006/12/15) USER.LASTACCESS情報を追加します。
529         * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属性(CLS_NM)から、DBTYPEに変更
530         * @og.rev 4.4.0.1 (2009/08/08) 最終ログイン画面名称を追加
531         * @og.rev 5.6.6.0 (2013/07/05) table作成処理を、変更します。
532         * @og.rev 6.3.6.1 (2015/08/28) <table> 枠の指定と、</table> の static final String 化
533         * @og.rev 5.9.1.2 (2015/10/23) 自己終了警告対応
534         * @og.rev 7.0.4.0 (2019/05/31) colgroup 廃止
535         * @og.rev 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
536         *
537         * @param       sort    ソートするキー項目を指定
538         * @param       direc   ソートする方向 [true:昇順/false:降順]
539         *
540         * @return      loginUser情報
541         * @og.rtnNotNull
542         */
543        private String getLoginUser( final String sort,final boolean direc ) {
544                // 4.0.0 (2005/01/31) ログイン数の取得方法の変更。
545                final int loginCount = SystemManager.getRunningCount() ;
546
547                // 4.0.0 (2005/01/31)
548                final UserSummary[] userInfos = SystemManager.getRunningUserSummary( sort,direc );
549
550                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
551                        .append( "現在 "   ).append( loginCount   ).append( " 名の方がログイン中です。" ).append( CR )
552                        .append( "<table " ).append( TABLE_HEADER ).append( " >" )
553                        .append( "<thead><tr><th>No</th>" );
554
555                // 5.6.6.0 (2013/07/05) table作成処理を、変更します。
556                for( final String sortKey : USER_KEYS ) {
557                        rtn.append( "<th><a href=\"?COMMAND=loginUser&sort=" ).append( sortKey )
558                                .append( "&direc=" ).append( !direc )
559                                .append( "\">" ).append( sortKey ).append( "</a></th>" );
560                }
561
562                // 7.0.4.0 (2019/05/31) colgroup 廃止
563                rtn.append( "</tr></thead>" ).append( CR )
564                        .append( CR );
565
566//              for( int i=0; i<userInfos.length; i++ ) {
567//                      final UserSummary userInfo = userInfos[i] ;
568//                      rtn.append( " <tr class=\"row_" ).append( i%2 ).append( "\" >" )
569//                              .append( "<td class='S9'>" ).append( String.valueOf( i+1 )      ).append( "</td>"       )       // 7.0.4.0 (2019/05/31)
570//                              .append( "<td>" ).append( userInfo.getUserID()                          ).append( "</td>"       )
571//                              .append( "<td>" ).append( userInfo.getJname()                           ).append( "</td>"       )
572//                              .append( "<td>" ).append( userInfo.getRoles()                           ).append( "</td>"       )
573//                              .append( "<td>" ).append( userInfo.getIPAddress()                       ).append( "</td>"       )
574//                              .append( "<td>" ).append( HybsSystem.getDate( userInfo.getLoginTime() ) ).append( "</td>" )
575//                              .append( "<td>" ).append( userInfo.getAttribute( "LASTACCESS" )                 ).append( "</td>" )
576//                              .append( "<td>" ).append( StringUtil.nval( userInfo.getAttribute( "LASTGAMENNM" ), "" ) ).append( "</td>" )     // 4.4.0.1 (2009/08/08)
577//                              .append( " </tr>" ).append( CR );
578//              }
579
580                // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
581                for( int i=0; i<userInfos.length; i++ ) {
582                        final UserSummary userInfo = userInfos[i] ;
583                        rtn.append( " <tr class=\"row_" ).append( i%2 )
584                                .append( "\" ><td class='S9'>" ).append( String.valueOf( i+1 )  )       // 7.0.4.0 (2019/05/31)
585                                .append( TD_TD ).append( userInfo.getUserID()                   )
586                                .append( TD_TD ).append( userInfo.getJname()                    )
587                                .append( TD_TD ).append( userInfo.getRoles()                    )
588                                .append( TD_TD ).append( userInfo.getIPAddress()                )
589                                .append( TD_TD ).append( HybsSystem.getDate( userInfo.getLoginTime() ) )
590                                .append( TD_TD ).append( userInfo.getAttribute( "LASTACCESS" )                  )
591                                .append( TD_TD ).append( StringUtil.nval( userInfo.getAttribute( "LASTGAMENNM" ), "" ) )        // 4.4.0.1 (2009/08/08)
592                                .append( TD_TR );
593                }
594                return rtn.append( TABLE_END ).toString();
595        }
596
597        /**
598         * PlugIn 情報を作成します。
599         *
600         * @og.rev 4.0.0.0 (2005/08/31) 新規作成
601         * @og.rev 5.6.6.0 (2013/07/05) "DBConstValue","Daemon","JspCreate" を、追加します。
602         * @og.rev 7.1.0.0 (2020/01/27) pluginType をstatic で定義しておきます。
603         *
604         * @return      PlugIn情報
605         * @og.rtnNotNull
606         */
607        private String getPlugInInfo() {
608                final ClassInfo info = new ClassInfo();
609
610                for( int j=0; j<PLUGIN_TYPE.length; j++ ) {
611                        final String type = PLUGIN_TYPE[j] ;
612                        final HybsEntry[] names = HybsSystem.sysEntry( type + "_" );
613                        for( int i=0; i<names.length; i++ ) {
614                                final String key                = names[i].getKey().substring( type.length()+1 );
615                                final String clsName    = names[i].getValue();
616                                info.addLine( type,key,clsName );
617                        }
618                }
619                return info.getClassInfoData() ;
620        }
621
622        /**
623         * Taglib 情報を作成します。
624         *
625         * @og.rev 4.0.0.0 (2006/01/31) 新規作成
626         * @og.rev 5.3.6.0 (2011/06/01) Taglib クラス名の求め方を変更します。(jar版のみ)
627         * @og.rev 5.5.2.6 (2012/05/25) JarFile を、Closer#zipClose( ZipFile ) メソッドを利用して、close します。
628         * @og.rev 6.8.5.1 (2018/01/15) ファイル名は、##バージョン番号を変換しておく必要がある。
629         *
630         * @return      Taglib情報
631         * @og.rtnNotNull
632         */
633        private String getTaglibInfo() {
634                final ClassInfo info = new ClassInfo();
635
636                // 5.5.2.6 (2012/05/25) findbugs対応
637                JarFile jarFile = null;
638                try {
639                        final ClassLoader loader = Thread.currentThread().getContextClassLoader();
640                        final Enumeration<URL> enume = loader.getResources( "org/opengion/hayabusa/taglib/" );  // 4.3.3.6 (2008/11/15) Generics警告対応
641                        while( enume.hasMoreElements() ) {
642                                final URL url = enume.nextElement();                                                    // 4.3.3.6 (2008/11/15) Generics警告対応
643                                // jar:file:/実ディレクトリ または、file:/実ディレクトリ
644                                final String dir = url.getFile().replaceAll( "%23%23","##" );   // 6.8.5.1 (2018/01/15)
645                                if( "jar".equals( url.getProtocol() ) ) {
646                                        // dir = file:/G:/webapps/gf/WEB-INF/lib/hayabusa4.0.0.jar!/org/opengion/hayabusa/taglib 形式です。
647                                        final String jar = dir.substring(dir.indexOf( ':' )+1,dir.lastIndexOf( '!' ));
648                                        // jar = /G:/webapps/gf/WEB-INF/lib/hayabusa4.0.0.jar 形式に切り出します。
649                                        jarFile = new JarFile( jar );
650                                        final Enumeration<JarEntry> en = jarFile.entries() ;            // 4.3.3.6 (2008/11/15) Generics警告対応
651                                        while( en.hasMoreElements() ) {
652                                                final JarEntry ent = en.nextElement();                                  // 4.3.3.6 (2008/11/15) Generics警告対応
653                                                final String file = ent.getName();
654                                                if( ! ent.isDirectory() && file.endsWith( "Tag.class" ) ) {
655                                                        final String type               = "Taglib_jar";
656                                                        // 5.3.6.0 (2011/06/01) Taglib クラス名の求め方を変更します。(jar版のみ)
657                                                        final String key                = file.substring( file.lastIndexOf( '/' )+1,file.length()-6 );  // -6 は、.class 分
658                                                        final String clsName    = file.replace( '/','.' ).substring( 0,file.length()-6 );
659                                                        info.addLine( type,key,clsName );
660                                                }
661                                        }
662                                        Closer.zipClose( jarFile );                                                                     // 5.5.2.6 (2012/05/25) findbugs対応
663                                        jarFile = null;                                                                                         // 正常終了時に、close() が2回呼ばれるのを防ぐため。
664                                }
665                                else {
666                                        // dir = /G:/webapps/gf/WEB-INF/classes/org/opengion/hayabusa/taglib/ 形式です。
667                                        final File[] list = new File( dir ).listFiles();
668                                        // 6.3.9.0 (2015/11/06) null になっている可能性がある(findbugs)
669                                        if( list != null ) {
670                                                for( final File file : list ) {
671                                                        final String name = file.getName() ;
672                                                        if( file.isFile() && name.endsWith( "Tag.class" ) ) {
673                                                                final String type               = "Taglib_file";
674                                                                final String key                = name.substring( 0,name.length()-6 );
675                                                                final String clsName    = "org.opengion.hayabusa.taglib." + key ;
676                                                                info.addLine( type,key,clsName );
677                                                        }
678                                                }
679                                        }
680                                }
681                        }
682                }
683                catch( final IOException ex ) {
684                        final String errMsg = "taglibファイル読み取りストリームを失敗しました。"
685                                        + CR + ex.getMessage();
686                        throw new OgRuntimeException( errMsg,ex );
687                }
688                finally {
689                        Closer.zipClose( jarFile );             // 5.5.2.6 (2012/05/25) findbugs対応
690                }
691
692                return info.getClassInfoData() ;
693        }
694
695        /**
696         * クラス情報を表示するためのデータを管理します。
697         * ここでは、引数に渡された、分類(Classify)、名称(Key Name)、クラス名(Class Name)、
698         * バージョン(Version)情報をテーブル形式で表示します。
699         * バージョン情報は、クラス名から、インスタンスを作成して、private static final String VERSION
700         * フィールドの値を読み取ります。
701         *
702         * @og.rev 4.0.0.0 (2006/01/31) 新規作成
703         * @og.rev 7.0.4.0 (2019/05/31) colgroup 廃止
704         * @og.rev 7.1.0.0 (2020/01/27) ヘッダー部分をstatic で定義しておきます。
705         */
706        private static final class ClassInfo {
707                private static final String HEADER =
708                        "<table " + TABLE_HEADER + " >" + CR +
709                        "       <thead><tr><th>No</th><th>Classify</th><th>Key Name</th><th>Class Name</th><th>Version</th></tr></thead>" + CR ;
710
711                private final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
712                private int cnt;
713
714                /**
715                 * コンストラクター
716                 *
717                 * @og.rev 4.0.0.0 (2006/01/31) 新規作成
718                 * @og.rev 5.9.1.2 (2015/10/23) 自己終了警告対応
719                 * @og.rev 7.1.0.0 (2020/01/27) ヘッダー部分をstatic で定義しておきます。
720                 */
721                public ClassInfo() {
722                        rtn.append( HEADER );                   // 7.1.0.0 (2020/01/27)
723                }
724
725                /**
726                 * テーブル表示用のデータを追加します。
727                 *
728                 * @og.rev 4.0.0.0 (2006/01/31) 新規作成
729                 * @og.rev 7.0.4.0 (2019/05/31) colgroup 廃止
730                 * @og.rev 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
731                 *
732                 * @param       type    タイプ属性
733                 * @param       key     キー属性
734                 * @param       clsName クラス名(このクラス名からインスタンス化します。)
735                 */
736                public void addLine( final String type, final String key, final String clsName ) {
737                        final String version    = getFieldValue( clsName );
738
739                        final boolean isCustom =   version.compareTo( BuildNumber.VERSION_NO ) > 0
740                                                                        || version.indexOf( "Pache"   ) >= 0
741                                                                        || version.indexOf( "Nightly" ) >= 0 ;
742
743                        final String trType = isCustom ? "warning" : String.valueOf( cnt%2 );
744
745//                      rtn.append( "<tr class=\"row_" ).append( trType ).append( "\" >" )
746//                              .append( "<td class='S9'>"      ).append( cnt++         ).append( "</td>" )     // 7.0.4.0 (2019/05/31)
747//                              .append( "<td>"                         ).append( type          ).append( "</td>" )
748//                              .append( "<td>"                         ).append( key           ).append( "</td>" )
749//                              .append( "<td>"                         ).append( clsName       ).append( "</td>" )
750//                              .append( "<td>"                         ).append( version       ).append( "</td>" )
751//                              .append( "</tr>" ).append( CR );
752
753                        // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
754                        rtn.append( "<tr class=\"row_" ).append( trType )
755                                .append( "\" ><td class='S9'>"  ).append( cnt++         )                       // 7.0.4.0 (2019/05/31)
756                                .append( TD_TD ).append( type   )
757                                .append( TD_TD ).append( key            )
758                                .append( TD_TD ).append( clsName        )
759                                .append( TD_TD ).append( version        )
760                                .append( TD_TR );
761                }
762
763                /**
764                 * すべての内部のデータを文字列化して返します。
765                 *
766                 * @og.rev 4.0.0.0 (2006/01/31) 新規作成
767                 * @og.rev 6.3.6.1 (2015/08/28) <table> 枠の指定と、</table> の static final String 化
768                 *
769                 * @return      作成されたテーブルデータ
770                 * @og.rtnNotNull
771                 */
772                public String getClassInfoData() {
773                        return rtn.append( TABLE_END ).toString();
774                }
775
776                /**
777                 * 指定のオブジェクトの  VERSION staticフィールドの値を取得します。
778                 *
779                 * @og.rev 4.0.0.0 (2005/08/31) 新規作成
780                 * @og.rev 6.4.3.3 (2016/03/04) HybsSystem#newInstance(String) ではなく、直接Class#forName(String)から、求めます。
781                 *
782                 * @param       clsName 指定のクラスを表す名称
783                 * @return      VERSIONフィールドの値(エラー時は、そのメッセージ)
784                 */
785                private String getFieldValue( final String clsName ) {
786                        String rtn ;
787                        try {
788                                final Field fld = Class.forName( clsName ).getDeclaredField( "VERSION" ) ;
789
790                                // privateフィールドの取得には、accessibleフラグを trueにする必要があります。
791                                fld.setAccessible( true );
792
793                                rtn = (String)fld.get( null );
794                        }
795                        catch( final Throwable ex ) {
796                                rtn = ex.getMessage();
797                        }
798                        return rtn ;
799                }
800        }
801
802        /**
803         * systemResource 情報を作成します。
804         *
805         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
806         * @og.rev 4.0.0.0 (2005/01/31) DBColumn の 属性(CLS_NM)から、DBTYPEに変更
807         * @og.rev 6.3.6.1 (2015/08/28) <table> 枠の指定と、</table> の static final String 化
808         * @og.rev 5.9.1.2 (2015/10/23) 自己終了警告対応
809         * @og.rev 6.4.3.3 (2016/03/04) 配列返しではなく、Map を返します。
810         * @og.rev 7.0.4.0 (2019/05/31) colgroup 廃止
811         * @og.rev 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
812         *
813         * @return      systemResource情報
814         * @og.rtnNotNull
815         */
816        private String getSystemResource() {
817                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
818                        .append( "<table " ).append( TABLE_HEADER ).append( " >" ).append( CR )
819                        .append( "<thead><tr><th>No</th><th>Key</th><th>Value</th></tr></thead>" ).append( CR )
820                        .append( CR );
821
822                // 6.4.3.3 (2016/03/04) 配列返しではなく、Map を返します。
823                final ConcurrentMap<String,String> rscMap = HybsSystem.getSystemResourceMap();
824                int i=0;
825//              for( final Map.Entry<String,String> entry : rscMap.entrySet() ) {
826//                      rtn.append( "<tr class=\"row_" ).append( i%2 ).append( "\" >" ).append( CR )
827//                              .append( "<td class='S9'>" ).append( ++i        ).append( "</td>" )     // 7.0.4.0 (2019/05/31)
828//                              .append( "<td>" ).append( entry.getKey()        ).append( "</td>" )
829//                              .append( "<td>" ).append( entry.getValue()      ).append( "</td>" )
830//                              .append( "</tr>" ).append( CR );
831//              }
832                // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
833                for( final Map.Entry<String,String> entry : rscMap.entrySet() ) {
834                        rtn.append( "<tr class=\"row_" ).append( i%2 )
835                                .append( "\" ><td class='S9'>" ).append( ++i )                                  // 7.0.4.0 (2019/05/31)
836                                .append( TD_TD ).append( entry.getKey()         )
837                                .append( TD_TD ).append( entry.getValue()       )
838                                .append( TD_TR );
839                }
840                return rtn.append( TABLE_END ).toString();
841        }
842
843        /**
844         * AccessStop 情報を作成します。
845         *
846         * @og.rev 3.5.3.1 (2003/10/31) 機能ごとにメソッドを呼び出すように修正します。
847         * @og.rev 4.0.0.0 (2007/11/29) AccessStopFilter#getStopFilter() ⇒ isStopFilter() に変更
848         * @og.rev 6.1.1.0 (2015/01/17) パッケージを import するのと、ロジック見直し。
849         * @og.rev 6.3.8.0 (2015/09/11) AccessStop を外部から制御できるように、コマンドと状態を受けるようにする。
850         * @og.rev 7.1.0.0 (2020/01/20) 本物のサービスと混同しないようにメッセージを変更します。
851         *
852         * @param       isStop          true:停止/false:実行
853         * @return      AccessStop情報
854         * @og.rtnNotNull
855         */
856        private String getAccessStop( final String isStop ) {
857                final boolean flag = Boolean.parseBoolean( isStop );                                    // 6.3.8.0 (2015/09/11)
858
859                return flag ? "Webアプリケーションへのアクセスを停止します。"
860                                        : "Webアプリケーションへのアクセスを開始します。";
861        }
862
863//      /**
864//       * fileexecのMainProcess 情報を作成します。
865//       *
866//       * @og.rev 7.2.5.0 (2020/06/01) fileexecのMainProcess の処理が起動しているかどうかを表示
867//       *
868//       * @param       isStart         true:実行/false停止:
869//       * @return      fileexec情報
870//       * @og.rtnNotNull
871//       */
872//      private String getFileExecInfo( final String isStart ) {
873//              final String reload = "<script>parent.QUERY.location.reload(true);</script>" ;
874//
875//              final String msg ;
876//
877//              if( Boolean.parseBoolean( isStart ) ) {
878//                      MainProcess.start();
879//                      msg = "ファイル取込処理を実行しました。";
880//              }
881//              else {
882//                      MainProcess.shutdown( false );  // 再実行できるようにしておきます。
883//                      msg = "ファイル取込処理を停止しました。";
884//              }
885//
886//              return msg + reload;
887//      }
888
889        /**
890         * application オブジェクトに関連付ける 共通メッセージを設定します。
891         *
892         * 取り出しは、errorMessageタグで行います。これは、個々のrequest.jsp に組み込まれている
893         * メッセージなので、ここで登録したメッセージは、同時に、すべてのアクセスしているユーザーが
894         * 見ることになります。
895         *
896         * @og.rev 6.4.4.1 (2016/03/18) application オブジェクトに関連付ける 共通メッセージを設定します。
897         * @og.rev 6.8.5.0 (2018/01/09) 共通メッセージで、strongタグのバグ修正と、class="common_msg" 追加。
898         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
899         *
900         * @param       type    [set/clear] を指定します。
901         * @param       message 共通メッセージを指定します。
902         * @param       session HttpSessionオブジェクト
903         *
904         * @return      Servlet/Filter情報
905         * @og.rtnNotNull
906         */
907        private String setCommonMessage( final String type , final String message , final HttpSession session ) {
908                final ServletContext context = session.getServletContext();
909
910                String rtMsg = "";
911                if( "set".equalsIgnoreCase( type ) && message != null && message.length() > 0 ) {
912                        rtMsg = "<strong class=\"common_msg\">" + message + "</strong><br>";    // 7.0.1.0 (2018/10/15)
913                        context.setAttribute( HybsSystem.COMMON_MSG_KEY,rtMsg );
914                }
915                else if( "get".equalsIgnoreCase( type ) ) {
916                        rtMsg = (String)context.getAttribute( HybsSystem.COMMON_MSG_KEY );
917                }
918                else if( "clear".equalsIgnoreCase( type ) ) {
919                        context.removeAttribute( HybsSystem.COMMON_MSG_KEY );
920                }
921
922                return rtMsg;
923        }
924
925        /**
926         * Servlet/Filter 情報を作成します。
927         *
928         * @og.rev 6.3.8.3 (2015/10/03) Servlet/Filter 情報を作成。
929         * @og.rev 5.9.1.2 (2015/10/23) 自己終了警告対応
930         * @og.rev 7.0.4.0 (2019/05/31) colgroup 廃止
931         * @og.rev 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
932         *
933         * @param       session HttpSessionオブジェクト
934         *
935         * @return      Servlet/Filter情報
936         * @og.rtnNotNull
937         */
938        private String getRegistrationMessage( final HttpSession session ) {
939                final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE )
940                        // 速度よりソースの見易さ
941                        .append( "<table " ).append( TABLE_HEADER ).append( " >" )
942                        .append( "<thead><tr><th>No</th><th>Type</th><th>Key</th><th>Class</th><th>Mappings</th></tr></thead>" )
943                        .append( CR );
944
945                int no = 0;
946                final ServletContext context = session.getServletContext();
947                for( final ServletRegistration reg : context.getServletRegistrations().values() ) {
948//                      // 速度よりソースの見易さ
949//                      rtn.append( "<tr class=\"row_" ).append( no%2 ).append( "\" >" )
950//                              .append( "<td class='S9'>" ).append( String.valueOf( ++no ) ).append( "</td>" ) // 7.0.4.0 (2019/05/31)
951//                              .append( "<td>Servlet</td>" )
952//                              .append( "<td>" ).append( reg.getName()                 ).append( "</td>" )
953//                              .append( "<td>" ).append( reg.getClassName()    ).append( "</td>" )
954//                              .append( "<td>" ).append( reg.getMappings()             ).append( "</td>" )
955//                              .append( "</tr>" ).append( CR );
956                        // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
957                        rtn.append( "<tr class=\"row_" ).append( no%2 )
958                                .append( "\" ><td class='S9'>" ).append( String.valueOf( ++no ) )       // 7.0.4.0 (2019/05/31)
959                                .append( TD_TD ).append( "Servlet"                      )
960                                .append( TD_TD ).append( reg.getName()          )
961                                .append( TD_TD ).append( reg.getClassName()     )
962                                .append( TD_TD ).append( reg.getMappings()      )
963                                .append( TD_TR );
964                }
965
966                for( final FilterRegistration reg : context.getFilterRegistrations().values() ) {
967//                      // 速度よりソースの見易さ
968//                      rtn.append( "<tr class=\"row_" ).append( no%2 ).append( "\" >" )
969//                              .append( "<td class='S9'>" ).append( String.valueOf( ++no )       ).append( "</td>" )   // 7.0.4.0 (2019/05/31)
970//                              .append( "<td>Filter</td>" )
971//                              .append( "<td>" ).append( reg.getName()                           ).append( "</td>" )
972//                              .append( "<td>" ).append( reg.getClassName()              ).append( "</td>" )
973//                              .append( "<td>" ).append( reg.getUrlPatternMappings() ).append( "</td>" )
974//                              .append( "</tr>" ).append( CR );
975                        // 7.2.6.0 (2020/06/30) StringBuilderの連結部見直し
976                        rtn.append( "<tr class=\"row_" ).append( no%2 )
977                                .append( "\" ><td class='S9'>" ).append( String.valueOf( ++no ) )       // 7.0.4.0 (2019/05/31)
978                                .append( TD_TD ).append( "Filter"                                               )
979                                .append( TD_TD ).append( reg.getName()                                  )
980                                .append( TD_TD ).append( reg.getClassName()                             )
981                                .append( TD_TD ).append( reg.getUrlPatternMappings()    )
982                                .append( TD_TR );
983                }
984                return rtn.append( TABLE_END ).toString();
985        }
986
987        /**
988         * admin リンク情報を作成します。
989         * 簡易メソッドなので、国際化対応していません。
990         *
991         * @og.rev 3.5.4.1 (2003/12/01) 新規作成
992         * @og.rev 5.1.1.2 (2009/12/10) 画面IDを変更
993         * @og.rev 5.6.3.4 (2013/04/26) クイックリファレンス 画面を追加
994         * @og.rev 6.3.6.1 (2015/08/28) <table> 枠の指定と、</table> の static final String 化
995         * @og.rev 6.3.8.0 (2015/09/11) AccessStop を外部から制御できるように、コマンドと状態を受けるようにする。
996         * @og.rev 6.9.2.1 (2018/03/12) リンクが横に長くなってきたので、2段に折り返します。
997         * @og.rev 7.0.0.1 (2018/10/09) 一旦、[プラグイン情報],[タグリブ情報],[Servlet/Filter情報],[システム状況] を削除します。
998         * @og.rev 7.0.1.0 (2018/10/15) XHTML → HTML5 対応(空要素の、"/>" 止めを、">" に変更します)。
999         * @og.rev 7.1.0.0 (2020/01/20) logLink.jsp 、serviceRestart.jsp 追加。AccessStopのON/OFF追加
1000         * @og.rev 7.1.0.0 (2020/01/27) static で定義しておきます。
1001         *
1002         * @return      アドミンリンク情報
1003         * @og.rtnNotNull
1004         */
1005        private String getAdminLink() {
1006                // 7.1.0.0 (2020/01/20) AccessStopのON/OFF追加
1007                final String accessStop = "true".equalsIgnoreCase( System.getProperty( "AccessStopFilter" ) )
1008                                                                                ? ACCESS_STOP : "" ;
1009
1010                // 7.1.0.0 (2020/01/20) logLink.jsp 、serviceRestart.jsp 追加
1011                final String serviceRestart = "true".equalsIgnoreCase( HybsSystem.sys( "IS_SERVICE" ) )
1012                                                                                ? SERVICE_RESTART : "" ;
1013
1014                // 7.1.0.0 (2020/01/27) static で定義しておきます。
1015                return new StringBuilder( BUFFER_MIDDLE )
1016                        .append( "<style> body { overflow-y: hidden; } </style>" )
1017                        .append( "<table><tr>"   ).append( CR )
1018                        .append( INFOMATION              )
1019                        .append( CLOSE                   )
1020                        .append( LOGIN_USER              )
1021                        .append( QUICK_REFERENCE )
1022                        .append( SYSTEM_RESOURCE )
1023                        .append( PARAMETER               )
1024                        .append( LOGLINK                 )
1025                        .append( serviceRestart  )
1026//                      .append( "</tr>" ).append( CR ).append( "<tr><td /><td />" ).append( CR )
1027                        .append( "</tr>" ).append( CR ).append( "<tr><td />" ).append( CR )     // 7.2.5.0 (2020/06/01)
1028                        .append( PLUGIN                  )
1029                        .append( TAGLIB                  )
1030                        .append( REGISTRATION    )
1031                        .append( SYSTEM_INFO     )
1032                        .append( accessStop              )
1033        //              .append( fileExecCmnt()  )                                                                                      // 7.2.5.0 (2020/06/01)
1034                        .append( "</tr>" ).append( TABLE_END )
1035                        .toString();
1036        }
1037
1038        /**
1039         * DBTableModel から テーブルのタグ文字列を作成して返します。
1040         *
1041         * @og.rev 3.5.3.1 (2003/10/31) User情報のテーブルの設定を、システムリソース より行う。
1042         * @og.rev 5.2.2.0 (2010/11/01) SystemData 見直し漏れの対応。
1043         *
1044         * @return      テーブルのタグ文字列
1045         * @og.rtnNotNull
1046         */
1047        private static String getTableHeaderTag() {
1048                // 6.1.1.0 (2015/01/17) Attributesの連結記述
1049                return new Attributes()
1050                                        .set( "id"              ,"viewTable"    )                                                       // 3.6.0.5 (2004/10/18)
1051                                        .set( "summary" ,"layout"               )                                                       // サマリー
1052                                        .getAttribute();
1053        }
1054
1055        /**
1056         * userInfo 情報をセットします。
1057         * 現状、このメソッドではLANGのみ設定可能です。
1058         * (予約語以外のセットはuserInfoタグで行う)
1059         *
1060         * LANGではuserInfoを切り替えた後にユーザのGUIInfoを再ロードします。
1061         *
1062         * @og.rev 5.9.1.0 (2015/10/02) 新規作成
1063         *
1064         * @param       req     HttpServletRequestオブジェクト
1065         * @return      結果情報
1066         */
1067        private String setUserinfo( final HttpServletRequest req ) {
1068                final HttpSession session = req.getSession();
1069                final UserInfo userInfo = (UserInfo)(session.getAttribute( HybsSystem.USERINFO_KEY ));
1070
1071                final String infoLang = req.getParameter( "LANG" );
1072
1073                String rtn = null ;
1074                if( userInfo != null && infoLang != null && infoLang.length() > 0) {
1075                        userInfo.setLang( infoLang );
1076                        ResourceFactory.newInstance( userInfo.getLang() ).makeGUIInfos( userInfo );
1077                        rtn = "User language : " + infoLang;
1078                }
1079
1080                if( rtn == null || rtn.length() == 0 ) {
1081                        rtn = "Error";
1082                }
1083
1084                return rtn ;
1085        }
1086}