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.FileInputStream; 019import java.io.IOException; 020import java.io.PrintWriter; 021import java.io.UnsupportedEncodingException; 022import java.util.Enumeration; 023import java.util.HashMap; 024 025import java.util.regex.Pattern; // 7.2.9.4 (2020/11/20) 026import java.util.regex.Matcher; // 7.2.9.4 (2020/11/20) 027 028import javax.servlet.ServletException; 029import javax.servlet.ServletConfig; // 7.2.9.4 (2020/11/20) 030import javax.servlet.ServletOutputStream; 031import javax.servlet.http.HttpServlet; 032import javax.servlet.http.HttpServletRequest; 033import javax.servlet.http.HttpServletResponse; 034 035import org.opengion.fukurou.system.Closer; 036import org.opengion.hayabusa.common.HybsSystem; 037import org.opengion.hayabusa.common.HybsSystemException; 038import org.opengion.hayabusa.remote.RemoteControllable; 039 040/** 041 * 外部からキーと値を投げて処理をさせるサーブレットです。 042 * Post,Get両方に対応しています。 043 * classキーが必須です。(値はhayabusa/remote/内のクラス名) 044 * 045 * @og.rev 4.1.0.0 (2007/12/20) 新規作成 046 * @version 4.1 047 * @author Masakazu Takahashi 048 * @since JDK6.0, 049 * 050 */ 051public class RemoteControlServlet extends HttpServlet { 052 private static final long serialVersionUID = 542020111201L ; 053 private static final String REMOTE_PKG = "org.opengion.hayabusa.remote."; 054 055 private Pattern filePattern ; // 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 056 057 /** 058 * デフォルトコンストラクター 059 * 060 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 061 */ 062 public RemoteControlServlet() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 063 064 /** 065 * Postメソッドで与えられたrequestをcallClassメソッドに渡します。 066 * callClassメソッドではclassパラメータの値を利用してクラスをロードし、処理を行います。 067 * 具体的な処理はcallClassメソッドをご覧下さい。 068 * 069 * @param request HttpServletRequestリクエスト 070 * @param response HttpServletResponseレスポンス 071 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 072 * @throws IOException 入出力エラーが発生したとき 073 */ 074 @Override 075 public void doPost( final HttpServletRequest request, final HttpServletResponse response ) throws ServletException, IOException { 076 callClass( request, response ); 077 } 078 079 /** 080 * Getメソッドで与えられたrequestをcallClassメソッドに渡します。 081 * callClassメソッドではclassパラメータの値を利用してクラスをロードし、処理を行います。 082 * 具体的な処理はcallClassメソッドをご覧下さい。 083 * 084 * @param request HttpServletRequestリクエスト 085 * @param response HttpServletResponseレスポンス 086 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 087 * @throws IOException 入出力エラーが発生したとき 088 */ 089 @Override 090 public void doGet( final HttpServletRequest request, final HttpServletResponse response ) throws ServletException, IOException { 091 callClass( request, response ); 092 } 093 094 /** 095 * Servlet の 初期値設定を行います。 096 * 097 * WEB-INF/web.xml ファイルで、<servlet> タグ内で初期値設定を行います。 098 * <init-param> 099 * <param-name>filePattern</param-name> 100 * <param-value>c:/opengionV7|c:/temp</param-value> 101 * </init-param> 102 * 103 * @og.rev 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 104 * 105 * @param config ServletConfigオブジェクト 106 */ 107 @Override 108 public void init( final ServletConfig config ) throws ServletException { 109 super.init( config ); 110 111 final String filePtn = config.getInitParameter("filePattern"); 112 if( filePtn != null && !filePtn.isEmpty() ) { 113 filePattern = Pattern.compile( filePtn ); 114 } 115 } 116 117 /** 118 * POSTとGETに対する実際の処理です 119 * 必須パラメータclassで与えられたクラス名でorg.opengion.hayabusa.remoteから 120 * クラスをロードし、MAPに格納したrequestパラメータをそのクラスに対して渡します。 121 * ロードするクラスはRemoteControllableを実装している必要があります。 122 * ロードしたクラスの処理が終了すると、返されたStringをresponseに出力して終了します。 123 * なお、classパラメータがnullの場合は何もせずに終了します。 124 * 125 * @og.rev 5.4.2.0 (2011/12/01) フォワード対応 126 * @og.rev 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 127 * 128 * @param request リクエスト 129 * @param response レスポンス 130 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。 131 * @throws IOException 入出力エラーが発生したとき 132 */ 133 private void callClass( final HttpServletRequest request, final HttpServletResponse response ) throws ServletException, IOException { 134 // 5.4.2.0 (2011/12/01) リクエストのエンコードを指定 135 try { 136 request.setCharacterEncoding( "UTF-8" ); 137 } 138 catch( final UnsupportedEncodingException ex ) { 139 throw new HybsSystemException( ex ); 140 } 141 142 // 5.4.2.0 (2011/12/01) フォワード対応 143 // 7.2.9.4 (2020/11/20) ファイルアクセスの制約(指定がない場合は、処理しない)。 144 final String file = request.getParameter( "file" ); 145// if( file != null && file.length() > 0 ) { 146 if( file != null && !file.isEmpty() && filePattern != null ) { // 7.2.9.4 (2020/11/20) 147 final Matcher match = filePattern.matcher( file ); // 7.2.9.4 (2020/11/20) 148 if( match.matches() ) { // 7.2.9.4 (2020/11/20) 149 response.setContentType( "application/octet-stream" ); 150 // ファイル内容の出力 151 FileInputStream fin = null; 152 ServletOutputStream out = null; 153 try { 154 // 対応済み:spotbugs:サーブレットの絶対パストラバーサル 155 fin = new FileInputStream( file ); 156 out = response.getOutputStream(); 157 158 // ファイル読み込み用バッファ 159 final byte buffer[] = new byte[4096]; 160 int size; 161 while((size = fin.read(buffer))!=-1) { 162 out.write(buffer,0, size); 163 out.flush(); 164 } 165 } 166 finally { 167 Closer.ioClose( fin ); 168 Closer.ioClose( out ); 169 } 170 } 171 } 172 else { 173 final String clazz = request.getParameter( "class" ); // パラメータ"class"だけは必ず必要 174 if( clazz == null ) { 175 return; // 暫定処理 176 } 177 178 final Enumeration<?> paramEnm = request.getParameterNames(); // 4.3.3.6 (2008/11/15) Generics警告対応 179 final HashMap<String,String> paramMap = new HashMap<>(); 180 while( paramEnm.hasMoreElements() ) { 181 final String key = ( String )( paramEnm.nextElement() ); 182 paramMap.put( key, request.getParameter( key ) ); 183 } 184 185 final RemoteControllable rmtC = HybsSystem.newInstance( REMOTE_PKG + clazz ); 186 final String rtnString = rmtC.remoteControl( paramMap ); 187 response.setContentType( "text/xml; charset=UTF-8" ); 188 final PrintWriter out = response.getWriter(); 189 out.println( rtnString ); 190 out.flush(); 191 out.close(); 192 } 193 } 194}