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.taglib; 017 018import static org.opengion.fukurou.util.StringUtil.*; 019 020import java.io.File; 021import java.io.IOException; 022import java.util.ArrayList; 023import java.util.List; 024 025import javax.servlet.http.HttpServletRequest; 026 027import org.opengion.fukurou.util.StringUtil; 028import org.opengion.hayabusa.common.HybsSystem; 029import org.opengion.hayabusa.common.HybsSystemException; 030import org.opengion.hayabusa.db.DBColumn; 031import org.opengion.hayabusa.db.DBTableModel; 032import org.opengion.hayabusa.db.DBTableModelUtil; 033import org.opengion.hayabusa.servlet.MultipartRequest; 034import org.opengion.hayabusa.servlet.UploadedFile; 035 036/** 037 * クライアントのファイルをサーバーにアップロードするタグです。 038 * 039 * アップロード後の属性は、DBTableModel に格納することにより、通常のデータと 040 * 同様の取り出し方が可能です。 041 * また、通常のファイルアップロード時の、form で使用する、enctype="multipart/form-data" 042 * を指定した場合の、他のリクエスト情報も、{@XXXX} 変数で取り出すことが可能です。 043 * 044 * この upload タグでは、アップロード後に、指定のファイル名に変更する機能があります。 045 * file 登録ダイアログで指定した name に、"_NEW" という名称を付けたリクエスト値を 046 * ファイルのアップロードと同時に送信することで、この名前にファイルを付け替えます。 047 * また、アップロード後のファイル名は、name 指定の名称で、取り出せます。 048 * クライアントから登録したオリジナルのファイル名は、name に、"_ORG" という名称 049 * で取り出すことが可能です。 050 * 051 * 通常では、これらのパラメータを、RequestAttribute 変数にセットしますので、{@XXXX}で 052 * 取り出すことが可能になります。さらに、"KEY","VALUE","ISFILE" のカラムを持った、 053 * DBTableModel にセットします。 054 * 055 * 新機能として、columns を指定する事で、columns のカラムを持つ DBTableModel にセットします。 056 * その場合は、カラム名_01 〜 カラム名_99 のように、アンダーバーで列データとなるキーを定義してください。 057 * アンダーバーがない場合は、カラムだけ作成されます。カラム名と同じリクエストがあれば、 058 * すべてのレコードに同じ値がセットされます。 059 * 060 * 新ファイル名に拡張子が設定されていない場合は、オリジナルファイル名の拡張子をセットします。 061 * 062 * HTML5 の type="file" 時の multiple 属性(アップロードファイルの複数選択機能)に対応します。(5.7.1.1 (2013/12/13)) 063 * その場合は、新しいファイル名への変更はできません。オリジナルのファイル名でアップロードされます 064 * 065 * 5.7.1.2 (2013/12/20) zip 対応 066 * filename 属性に、".zip" の拡張子のファイル名を指定した場合は、アップロードされた一連のファイルを 067 * ZIP圧縮します。これは、アップロード後の処理になります。 068 * ZIP圧縮のオリジナルファイルは、そのまま残ります。 069 * なお、ZIPファイルは、useBackup属性を true に設定しても、無関係に、上書きされます。 070 * 071 * 5.7.4.3 (2014/03/28) filename 属性のリクエスト変数対応 072 * filename 属性のみ、{@XXXX} のリクエスト変数が使えるようにします。 073 * 他のパラメータでは使えません。 074 * これは、multipart/form-data のリクエストでは、パートの分解処理をしないと、リクエスト変数が 075 * 拾えない為、リクエスト変数は、この、upload タグ以降でのみ利用可能でした。 076 * zip対応と関連付けて、filename 属性のみ、利用できるように、MultipartRequest 側の処理に組み込みます。 077 * 078 * 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 079 * 個々に指定したアップロードファイル名は、XXX_NEW や XXX_ORG で取得できますが、 080 * HTML5 の multiple 属性使用時や、アップロードされたファイルを一連で処理したい場合に 081 * ファイル名を、CSV形式で取り出せるようにします。 082 * キーは、共通で、UPLOAD_FILES とします。 083 * 084 * 5.9.25.0 (2017/10/06) 085 * クラウド上のPaaSでオブジェクトストレージを利用する際は以下のシステムリソースを設定してください。 086 * CLOUD_STORAGE,CLOUD_STORAGE_CONTAINER 087 * plugin/cloud内のクラスを利用してファイルアップロード(FileUploadタグ)、ダウンロード(FileDownloadサーブレット)をAPI経由で行います。 088 * プラグインが利用するjarファイルの配置は必要です。 089 * 090 * @og.formSample 091 * ●形式:<og:upload fileURL="…" maxPostSize="…" /> 092 * ●body:なし 093 * 094 * ●Tag定義: 095 * <og:upload 096 * fileURL 【TAG】ファイルをアップロードするディレクトリを指定します (初期値:FILE_URL[=filetemp/]) 097 * filename 【TAG】(通常使いません)ファイルを作成するときのファイル名をセットします 098 * maxPostSize 【TAG】最大転送サイズ(Byte)を指定します(初期値:10485760) 0,またはマイナスで無制限です。 099 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session) 100 * tableId 【TAG】(通常使いません)sessionから所得する DBTableModelオブジェクトの ID 101 * columns 【TAG】DBTableModel作成時に、指定のカラムの"_01"〜"_99"の添え字をレコードとして作成します。 102 * useBackup 【TAG】ファイルアップロード時に、すでに同名のファイルが存在した場合に、バックアップ処理(renameTo)するかどうか[true/false]を指定します(初期値:false) 103 * language 【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します 104 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 105 * /> 106 * 107 * ●使用例 : 108 * 【query.jsp】 109 * <form method="POST" action="result.jsp" enctype="multipart/form-data" target="RESULT"> 110 * <table summary="layout" > 111 * <tr><og:input type="text" name="submitter" value="{@USER.JNAME}" size="20" lbl="MSG0014" /></tr> 112 * <tr> 113 * <og:input type="file" name="file_01" size="30" lbl="MSG0015" /> 114 * <og:input name="file_01_NEW" size="10" lbl="FILENAME" /> 115 * </tr><tr> 116 * <og:input type="file" name="file_02" size="30" lbl="MSG0015" /> 117 * <og:input name="file_02_NEW" size="10" lbl="FILENAME" /> 118 * </tr><tr> 119 * <og:input type="file" name="file_03" size="30" lbl="MSG0015" /> 120 * <og:input name="file_03_NEW" size="10" lbl="FILENAME" /> 121 * </tr><tr> 122 * <og:column name="writable" value="false" /> 123 * </tr> 124 * </table> 125 * 126 * 【result.jsp】 127 * <og:upload 128 * fileURL = "{@USER.ID}" 129 * /> 130 * <br /> 131 * <og:message lbl="MSG0003" comment="ファイルの登録が完了しました。" /> 132 * 133 * <og:view 134 * command = "NEW" 135 * viewFormType = "HTMLTable" 136 * writable = "{@writable}" 137 * /> 138 * 139 * <table> 140 * <tr><og:input name="submitter" value="{@submitter}" /></tr> 141 * <tr><og:input name="writable" value="{@writable}" /></tr> 142 * <tr><og:input name="directory" value="{@directory}" /></tr> 143 * <tr><og:input name="file_01" value="{@file_01}" /></tr> 144 * <tr><og:input name="file_01_NEW" value="{@file_01_NEW}" /></tr> 145 * <tr><og:input name="file_01_ORG" value="{@file_01_ORG}" /></tr> 146 * <tr><og:input name="file_02" value="{@file_02}" /></tr> 147 * <tr><og:input name="file_02_NEW" value="{@file_02_NEW}" /></tr> 148 * <tr><og:input name="file_02_ORG" value="{@file_02_ORG}" /></tr> 149 * <tr><og:input name="file_03" value="{@file_03}" /></tr> 150 * <tr><og:input name="file_03_NEW" value="{@file_03_NEW}" /></tr> 151 * <tr><og:input name="file_03_ORG" value="{@file_03_ORG}" /></tr> 152 * </table> 153 * 154 * 【result.jsp】 155 * <og:upload 156 * fileURL = "{@USER.ID}" 157 * columns = "submitter,file" 158 * /> 159 * <br /> 160 * <og:message lbl="MSG0003" comment="ファイルの登録が完了しました。" /> 161 * 162 * <og:view 163 * command = "NEW" 164 * viewFormType = "HTMLTable" 165 * writable = "{@writable}" 166 * /> 167 * 168 * @og.group ファイル入力 169 * 170 * @version 4.0 171 * @author Kazuhiko Hasegawa 172 * @since JDK5.0, 173 */ 174public class FileUploadTag extends CommonTagSupport { 175 //* このプログラムのVERSION文字列を設定します。 {@value} */ 176 private static final String VERSION = "5.7.6.3 (2014/05/23)" ; 177 178 private static final long serialVersionUID = 576320140523L ; 179 180 /** 5.7.6.3 (2014/05/23) アップロードファイルのCSVセットのキー */ 181 public static final String UPLOAD_FILES = "UPLOAD_FILES" ; 182 183 // 3.5.2.0 (2003/10/20) カラム名に、ISFILEを追加。 184 private static final String[] names = new String[] { "KEY","VALUE","ISFILE" }; 185 private static final String ENCODE = "UTF-8"; // 3.5.2.0 (2003/10/20) 廃止 186 private String fileURL = HybsSystem.sys( "FILE_URL" ); 187 private String filename = null; // 3.5.4.2 (2003/12/15) 188 189 private int maxPostSize = 10*1024*1024; // 最大ファイル容量 10MB 190 private String tableId = HybsSystem.TBL_MDL_KEY ; 191 192 // 5.6.5.2 (2013/06/21) DBTableModel作成時に、指定のカラムの"_01"〜"_99"の添え字をレコードとして作成します。 193 private String columns = null; 194 // 5.6.5.3 (2013/06/28) ファイルアップロード時に、すでに同名のファイルが存在した場合に、バックアップ処理(renameTo)するかどうか[true/false]を指定します(初期値:false) 195 private boolean useBackup = false; 196 197 /** 198 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 199 * 200 * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更 201 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 202 * @og.rev 3.1.3.0 (2003/04/10) UTF-8 決め打ちのエンコード情報を取得する。 203 * @og.rev 3.5.2.0 (2003/10/20) scope 属性を追加。 204 * @og.rev 3.5.4.2 (2003/12/15) ファイル名を指定できるようにします。 205 * @og.rev 3.6.0.8 (2004/11/19) DBTableModel をセーブする時に、トランザクションチェックを行います。 206 * @og.rev 3.7.1.1 (2005/05/23) フォルダがない場合は、複数階層分のフォルダを自動で作成します。 207 * @og.rev 3.8.1.3A (2006/01/30) 新ファイル名にオリジナルファイル名の拡張子をセットします 208 * @og.rev 5.3.7.0 (2011/07/01) エラーメッセージ内容変更 209 * @og.rev 5.6.5.2 (2013/06/21) columns 属性の追加 210 * @og.rev 5.6.5.3 (2013/06/28) useBackup 属性の追加 211 * @og.rev 5.8.8.0 (2015/06/05) エラー文の日本語化 212 * @og.rev 5.9.25.0 (2017/10/06) クラウドストレージの利用追加対応 213 * 214 * @return 後続処理の指示 215 */ 216 @Override 217 public int doEndTag() { 218 debugPrint(); // 4.0.0 (2005/02/28) 219 startQueryTransaction( tableId ); // 3.6.0.8 (2004/11/19) 220 HttpServletRequest request = (HttpServletRequest)getRequest(); 221 222 try { 223 String directory = HybsSystem.url2dir( fileURL ); 224 File dir = new File(directory); 225 if( ! dir.exists() && ! dir.mkdirs() ) { 226// String errMsg = "ディレクトリの作成に失敗しました。[" + directory + "]"; 227 String errMsg = getResource().getLabel( "ERR0043" ) + "[" + directory + "]"; // 5.8.8.0 (2015/06/05) 228 throw new HybsSystemException( errMsg ); 229 } 230 231 // 3.8.1.3A (2006/01/30) 新ファイル名にオリジナルファイル名の拡張子をセットします 232// MultipartRequest multi = new MultipartRequest( request,directory,maxPostSize,ENCODE,filename ); 233 // 5.6.5.3 (2013/06/28) useBackup 属性の追加 234 // 5.9.25.0 (2017/10/06) fileURL 属性の追加 235 MultipartRequest multi = new MultipartRequest( request,directory,maxPostSize,ENCODE,filename,useBackup,fileURL ); 236 // 5.6.5.2 (2013/06/21) columns 属性の追加 237// DBTableModel table = makeDBTable( multi ); 238 DBTableModel table = null; 239 if( columns == null ) { // 5.6.5.2 (2013/06/21) columns 属性の追加 240 table = makeDBTable( multi ); 241 } 242 else { 243 table = makeDBTableFromClms( multi ); 244 } 245 246 // 3.5.2.0 (2003/10/20) scope 属性を追加。 247 // 3.6.0.8 (2004/11/19) トランザクションチェックを行います。 248 if( ! commitTableObject( tableId, table ) ) { 249// jspPrint( "FileUploadTag Query処理が割り込まれました。DBTableModel は登録しません。" ); 250 jspPrint( "FileUploadTag " + getResource().getLabel( "ERR0041" ) ); // 5.8.8.0 (2015/06/05) 251 return (SKIP_PAGE); 252 } 253 254 } catch(IOException ex) { 255// String errMsg = "ファイルの取り扱い中にエラーが発生しました。" 256// + toString() + HybsSystem.CR 257// + "FileURL=" + fileURL + HybsSystem.CR 258// + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 259 260// String errMsg = "ファイル登録エラー!" 261 String errMsg = getResource().getLabel( "ERR0044" ) // 5.8.8.0 (2015/06/05) 262 + ex.getMessage() + HybsSystem.CR // 5.3.7.0 (2011/07/01) errMsg 修正 263 + "(" + toString() + HybsSystem.CR 264 + "FileURL=" + fileURL + ")"; 265 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 266 } 267 268 return(EVAL_PAGE); 269 } 270 271 /** 272 * タグリブオブジェクトをリリースします。 273 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 274 * 275 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 276 * @og.rev 3.0.1.1 (2003/03/06) columns を廃止 277 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 278 * @og.rev 3.5.4.2 (2003/12/15) ファイル名を指定できるようにします。 279 * @og.rev 5.6.5.2 (2013/06/21) columns 属性の追加 280 * @og.rev 5.6.5.2 (2013/06/21) useBackup 属性の追加 281 * 282 */ 283 @Override 284 protected void release2() { 285 super.release2(); 286 fileURL = HybsSystem.sys( "FILE_URL" ); 287 maxPostSize = 10*1024*1024; // 最大ファイル容量 10MB 288 tableId = HybsSystem.TBL_MDL_KEY ; 289 filename = null; // 3.5.4.2 (2003/12/15) 290 columns = null; // 5.6.5.2 (2013/06/21) 291 useBackup = false; // 5.6.5.3 (2013/06/28) 292 } 293 294 /** 295 * ファイルアップロードの実行結果を DBTableModel に記述します。 296 * 297 * ここでは、"KEY","VALUE","ISFILE" のカラムに対して、値を設定していきます。 298 * 同時に、RequestAttribute 変数に、これらの値をセットすることで、 299 * {@XXXX} で値が取り出せる様にしています。 300 * 301 * @og.rev 2.2.0.0 (2002/12/17) 中国語(国際化)対応 エンコードの取得方法変更 302 * @og.rev 3.0.1.1 (2003/03/06) request 情報から{@XXXX} で値が取り出せる様に修正。 303 * @og.rev 3.5.2.0 (2003/10/20) カラム名(KEY,VALUE)に ISFILE を追加 304 * @og.rev 3.5.6.5 (2004/08/09) MultipartRequest 変更に伴なう修正(Enum変更、元ファイル名取得) 305 * @og.rev 3.5.6.6 (2004/08/23) 上記変更時のバグ修正。 306 * @og.rev 3.5.6.6 (2004/08/23) 元ファイルのキーを、XXXX_ORG にします。 307 * @og.rev 4.0.0.0 (2007/10/12) テーブルモデルの登録方法を変更 308 * @og.rev 5.3.2.0 (2011/02/01) チェック行のパラメーターはint配列側に変換して復元する。パラメーター名を保存する。 309 * @og.rev 5.4.4.2 (2012/02/03) CommonTagSupportと同様のチェックボックス判定を行う 310 * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 311 * @og.rev 5.7.1.2 (2013/12/20) 5.7.1.2 (2013/12/20) zip対応で、UploadedFile のメソッド変更 312 * @og.rev 5.7.3.0 (2014/02/07) zip対応の修正で、取得ファイル名が異なっていた。 313 * @og.rev 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 314 * @og.rev 5.9.25.0 (2017/10/06) クラウド対応 315 * 316 * @param multi MultipartRequestオブジェクト 317 * 318 * @return テーブルモデル 319 */ 320 private DBTableModel makeDBTable( final MultipartRequest multi ) { 321 322 DBTableModel table = DBTableModelUtil.newDBTable(); 323 324 table.init( names.length ); 325 326 for( int i=0; i<names.length; i++ ) { 327 DBColumn dbColumn = getDBColumn( names[i] ); 328 table.setDBColumn( i,dbColumn ); 329 } 330 331 String[] values ; // 4.0.0.0 (2007/10/12) 332 List<String> prmNames = new ArrayList<String>(); 333 334 // 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 335 StringBuilder buf = new StringBuilder(); 336 337 // 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 338// String[] files = multi.getFilenames(); // 3.6.0.0 (2004/09/17) 339 UploadedFile[] files = multi.getUploadedFile(); 340 for( int i=0; i<files.length; i++ ) { 341// String name = files[i]; 342// File fin = multi.getFile(name); 343// File fin = files[i].getFile(); 344// if( fin != null ) { 345// String val = multi.getFilesystemName(name); 346 String name = files[i].getName(); // multiple対応では、キーがかぶることがある。 347// String val = files[i].getFilesystemName(); 348// String val = files[i].getUploadFile().getPath(); // 5.7.1.2 (2013/12/20) zip対応で、UploadedFile のメソッド変更 349// String val = files[i].getUploadFile().getName(); // 5.7.3.0 (2014/02/07) 取得ファイル名が異なっていた。 350 String val = files[i].getUploadFile(); // 5.9.25.0 (2017/10/06) MODIFY getUploadFileで取得される値をFileからStringに変更対応 351 352 // 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 353 if( i==0 ) { buf.append( val ); } 354 else { buf.append( "," ).append( val ); } // カンマ結合で、最初だけ結合しない。 355 356 // "KEY","VALUE","ISFILE" の順にデータを作成します。 357 values = new String[] { name, val, "1" }; 358 table.addColumnValues( values ); 359 setRequestAttribute( name,val ); 360 prmNames.add( name ); // 5.7.1.1 (2013/12/13) List に設定する。 361 362 String orgName = name + "_ORG" ; 363// val = multi.getOriginalFileName(name); // 注意:取得は、送信名 364 val = files[i].getOriginalFileName(); // 注意:取得は、送信名 365 366 // "KEY","VALUE","ISFILE" の順にデータを作成します。 367 values = new String[] { orgName, val, "2" }; 368 table.addColumnValues( values ); 369 setRequestAttribute( orgName,val ); 370// } 371 } 372 373 // 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 374 setRequestAttribute( UPLOAD_FILES,buf.toString() ); 375 376 // "KEY","VALUE","ISFILE" の順にデータを作成します。 377 values = new String[] { "directory", fileURL, "0" }; 378 table.addColumnValues( values ); 379 setRequestAttribute( "directory",fileURL ); 380 381 String[] params = multi.getParameterNames(); 382 for( int i=0; i<params.length; i++ ) { 383 String name = params[i]; 384 // 5.3.2.0 (2011/02/01) チェック行のパラメーターはint配列側に変換 385 if ( HybsSystem.ROW_SEL_KEY.equals( name ) ) { 386 setRequestAttribute( name,multi.getIntParameters(name) ); 387 } 388 else { 389 // 5.6.5.2 (2013/06/21) チェックボックス配列の値取得を考慮した、MultipartRequest のパラメータ値取得 390 String val = getParamVal( name,multi ); 391// String val = multi.getParameter(name); 392// // "KEY","VALUE","ISFILE" の順にデータを作成します。 393// if( "0".equals(val) ){ // 5.4.4.2 チェックボックス配列対応。 394// String[] vals = multi.getParameters(name); 395// if( vals != null && vals.length > 1 ) { 396// for( int j=0; j<vals.length; j++ ) { 397// if( "1".equals( vals[j] ) ) { 398// val = "1"; 399// break; 400// } 401// } 402// } 403// } 404 405 values = new String[] { name, val, "0" }; 406 table.addColumnValues( values ); 407 setRequestAttribute( name,val ); 408 prmNames.add( name ); // 5.7.1.1 (2013/12/13) List に設定する。 409 } 410 } 411 412 // 5.3.2.0 (2011/02/01) パラメーター名を保存する。 413 // 5.7.1.1 (2013/12/13) List に設定する。 414// String[] names = new String[ files.length + params.length ]; 415// System.arraycopy( files, 0, names, 0, files.length ); 416// System.arraycopy( params, 0, names, files.length, params.length ); 417// setParameterNames( names ); 418 setParameterNames( prmNames.toArray( new String[prmNames.size()] ) ); 419 420 return table ; 421 } 422 423 /** 424 * ファイルアップロードの実行結果を 横持の DBTableModel に記述します。 425 * 426 * この処理は、columns 属性を設定した場合のみとします。 427 * 428 * DBTableModel作成時に、指定のカラムの"_01"〜"_99"の添え字をレコードとして作成します。 429 * 現状は、"KEY","VALUE","ISFILE" のカラムに、データを縦持ちで作成しています。 430 * これを、横持で作成しますが、カラムの末尾に、"_01"〜"_99" までの添え字を 431 * 持つ場合は、これをレコードと認識させます。 432 * 添え字がない場合は、カラムだけ作成されます。カラム名と同じリクエストがあれば、 433 * すべてのレコードに同じ値がセットされます。 434 * 435 * @og.rev 5.6.5.2 (2013/06/21) 新規作成 436 * @og.rev 5.6.6.1 (2013/07/12) 添え字がない場合の処理の見直し 437 * @og.rev 5.7.1.2 (2013/12/20) zip対応で、UploadedFile のメソッド変更 438 * @og.rev 5.7.3.0 (2014/02/07) zip対応の修正で、取得ファイル名が異なっていた。 439 * @og.rev 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 440 * @og.rev 5.9.25.0 (2017/10/06) クラウド対応 441 * 442 * @param multi MultipartRequestオブジェクト 443 * 444 * @return テーブルモデル 445 */ 446 private DBTableModel makeDBTableFromClms( final MultipartRequest multi ) { 447 448 DBTableModel table = DBTableModelUtil.newDBTable(); 449 450 String[] clmNames = columns.split( "," ); 451 452 table.init( clmNames.length ); 453 454 // 値配列(1行分) 455 String[] rowVal = new String[clmNames.length]; 456 457 // 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 458 UploadedFile[] files = multi.getUploadedFile(); 459 460 List<String> prmNames = new ArrayList<String>(); 461 462 for( int i=0; i<clmNames.length; i++ ) { 463 String clm = clmNames[i] ; 464 DBColumn dbColumn = getDBColumn( clm ); 465 table.setDBColumn( i,dbColumn ); 466 467 // 先に、カラム名と一致するパラメータを初期値としてセットしておきます。 468 String val = getParamVal( clm,multi ); 469 470 // 5.6.6.1 (2013/07/12) ファイル名も同様に、あれば初期値セットしておきます。 471 if( val == null ) { 472 // 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 473// val = multi.getFilesystemName( clm ); 474 for( int j=0; j<files.length; j++ ) { 475 String nm = files[j].getName(); 476 if( clm.equalsIgnoreCase( nm ) ) { 477// val = files[j].getFilesystemName(); 478// val = files[i].getUploadFile().getPath(); // 5.7.1.2 (2013/12/20) zip対応で、UploadedFile のメソッド変更 479 //val = files[i].getUploadFile().getName(); // 5.7.3.0 (2014/02/07) 取得ファイル名が異なっていた。 480 val = files[i].getUploadFile(); // 5.9.25.0 (2017/10/06) getUploadFileの型をFileからStringに変更対応 481 break; // 5.7.6.3 (2014/05/23) たぶん有ったほうが良い。 482 } 483 } 484 } 485 // 5.7.1.1 (2013/12/13) getFilesystemName() の中に、newFile が null の場合は、original を返す処理がある。 486// if( val == null ) { 487// // 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 488//// val = multi.getOriginalFileName( clm ); // 注意:取得は、送信名 489// for( int j=0; j<files.length; j++ ) { 490// String nm = files[j].getName(); 491// if( clm.equalsIgnoreCase( nm ) ) { 492// val = files[j].getOriginalFileName(); 493// break; 494// } 495// } 496// } 497 rowVal[i] = ( val == null ) ? "" : val ; 498 } 499 500 // 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 501 StringBuilder buf = new StringBuilder(); 502 503// String[] files = multi.getFilenames(); // 3.6.0.0 (2004/09/17) 504 for( int i=0; i<files.length; i++ ) { 505// String name = files[i]; 506// File fin = multi.getFile(name); 507 String name = files[i].getName(); 508// File fin = files[i].getFile(); 509// if( fin != null ) { 510 // 5.6.6.1 (2013/07/12) 添え字がない場合の処理の見直し。先にレコードを作成 511 String[] values = new String[clmNames.length]; 512 System.arraycopy( rowVal,0,values,0,values.length ); // 行にセットするに当たり、rowVal を values にコピーしておく。 513 514 // ファイル名を Attribute で使えるようにセットしておく。 515// String fval = multi.getFilesystemName(name); 516// String fval = files[i].getFilesystemName(); 517// String fval = files[i].getUploadFile().getPath(); // 5.7.1.2 (2013/12/20) zip対応で、UploadedFile のメソッド変更 518// String fval = files[i].getUploadFile().getName(); // 5.7.3.0 (2014/02/07) 取得ファイル名が異なっていた。 519 String fval = files[i].getUploadFile(); // 5.9.25.0 (2017/10/06) getUploadで取得される値をFileからStringに変更 520 521 setRequestAttribute( name,fval ); 522 prmNames.add( name ); // 5.7.1.1 (2013/12/13) List に設定する。 523 524 // 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 525 if( i==0 ) { buf.append( fval ); } 526 else { buf.append( "," ).append( fval ); } // カンマ結合で、最初だけ結合しない。 527 528 String orgName = name + "_ORG" ; 529// String oval = multi.getOriginalFileName(name); // 注意:取得は、送信名 530 String oval = files[i].getOriginalFileName(); // 注意:取得は、送信名 531 setRequestAttribute( orgName,oval ); 532 533 // ファイルのキーを元に、添え字を検索します。 534 int adrs = name.lastIndexOf( '_' ); // 添え字は、'_' で区切られます。 535 // 5.6.6.1 (2013/07/12) 添え字がない場合の処理の見直し。後続処理を行う。 536// if( adrs < 0 ) { continue; } // 添え字がない 537 if( adrs > 0 ) { 538 String fnm = name.substring( 0,adrs ); // ファイル名(分割後) 539 String sub = name.substring( adrs ); // 添え字(アンダーバー含む) 540 541// String[] values = new String[clmNames.length]; 542// System.arraycopy( rowVal,0,values,0,values.length ); // 行にセットするに当たり、rowVal を values にコピーしておく。 543 544 // カラム名で検索しながら、レコード単位になるようにセットしていきます。 545 for( int j=0; j<clmNames.length; j++ ) { 546 String clm = clmNames[j] ; 547 String nm = null; 548 String val = null; 549 550 if( fnm.equalsIgnoreCase( clm ) ) { // ファイル名カラム(_NEWファイル名も、この値にすでに変わっている) 551// nm = name; 552// val = multi.getFilesystemName( nm ); 553 val = fval; 554 } 555 else if( ( fnm + "_ORG" ).equalsIgnoreCase( clm ) ) { // 元ファイル名カラム 556// nm = name + "_ORG" ; 557// val = multi.getOriginalFileName( name ); // 注意:取得は、送信名 558 val = oval; 559 } 560 else if( ( fnm + "_NEW" ).equalsIgnoreCase( clm ) ) { // 新ファイル名カラム 561 nm = name + "_NEW" ; 562 val = multi.getParameter( nm ); 563 } 564 else { 565 nm = clmNames[j] + sub; // sub は、アンダーバー含む添え字 566 // 5.6.5.2 (2013/06/21) チェックボックス配列の値取得を考慮した、MultipartRequest のパラメータ値取得 567 val = getParamVal( nm,multi ); 568 } 569 if( val != null ) { values[j] = val ; } // val が null でないときのみセットします。 570// setRequestAttribute( nm,val ); 571 } 572 } 573 table.addColumnValues( values ); 574// } 575 } 576 // 5.7.6.3 (2014/05/23) アップロードファイルのCSVセット 577 setRequestAttribute( UPLOAD_FILES,buf.toString() ); 578 579 // Attribute で使えるようにセットしておく。 580 setRequestAttribute( "directory",fileURL ); 581 582 // Attribute で使えるようにセットしておく。 583 String[] params = multi.getParameterNames(); 584 for( int i=0; i<params.length; i++ ) { 585 String name = params[i]; 586 // 5.3.2.0 (2011/02/01) チェック行のパラメーターはint配列側に変換 587 if ( HybsSystem.ROW_SEL_KEY.equals( name ) ) { 588 setRequestAttribute( name,multi.getIntParameters(name) ); 589 } 590 else { 591 // 5.6.5.2 (2013/06/21) チェックボックス配列の値取得を考慮した、MultipartRequest のパラメータ値取得 592 String val = getParamVal( name,multi ); 593 setRequestAttribute( name,val ); 594 prmNames.add( name ); // 5.7.1.1 (2013/12/13) List に設定する。 595 } 596 } 597 598 // 5.3.2.0 (2011/02/01) パラメーター名を保存する。 599 // 5.7.1.1 (2013/12/13) List に設定する。 600// String[] names = new String[ files.length + params.length ]; 601// System.arraycopy( files, 0, names, 0, files.length ); 602// System.arraycopy( params, 0, names, files.length, params.length ); 603// setParameterNames( names ); 604 setParameterNames( prmNames.toArray( new String[prmNames.size()] ) ); 605 606 return table ; 607 } 608 609 /** 610 * チェックボックス配列の値取得を考慮した、MultipartRequest のパラメータ値取得 611 * 612 * ここでは、、MultipartRequest のパラメータ値を取得します。 613 * 値の取得で、チェックボックス配列の場合は、取得した値が、"0" の場合のみ 614 * 配列でパラメータを取得し直し、"1" がないかどうか再度検索します。 615 * チェックボックスでは、チェック時の "1" と、チェックされなかった場合の、 616 * hidden の "0" の両方の値が配列としてリクエストされるケースがある為です。 617 * 618 * @og.rev 5.6.5.2 (2013/06/21) 新規作成 619 * 620 * @param key MultipartRequest のパラメータ取得のためのキー 621 * @param multi MultipartRequestオブジェクト 622 * 623 * @return チェックボックス配列を考慮したパラメータ値 624 */ 625 private String getParamVal( final String key , final MultipartRequest multi ) { 626 String val = multi.getParameter( key ); 627 628 if( "0".equals(val) ){ // 5.4.4.2 チェックボックス配列対応。 629 String[] vals = multi.getParameters( key ); 630 if( vals != null && vals.length > 1 ) { 631 for( int j=0; j<vals.length; j++ ) { 632 if( "1".equals( vals[j] ) ) { 633 val = "1"; 634 break; 635 } 636 } 637 } 638 } 639 return val ; 640 } 641 642 /** 643 * 【TAG】ファイルをアップロードするディレクトリを指定します 644 * (初期値:FILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。 645 * 646 * @og.tag 647 * この属性で指定されるディレクトリに、アップロードされたファイルをセーブします。 648 * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、 649 * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、 650 * fileURL = "{@USER.ID}" と指定すると、FILE_URL 属性で指定のフォルダの下に、 651 * さらに、各個人ID別のフォルダを作成して、そこにセーブします。 652 * (初期値:システム定数のFILE_URL[={@og.value org.opengion.hayabusa.common.SystemData#FILE_URL}])。 653 * 654 * @og.rev 4.0.0.0 (2005/01/31) StringUtil.urlAppend メソッドの利用 655 * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。 656 * @og.rev 5.7.1.1 (2013/12/13) リクエスト変数が使えないエラーを表示する。 657 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェックを行う。 658 * @og.rev 5.9.13.1 (2016/10/21) チェックは行わない 659 * 660 * @param url ファイルURL 661 * @see org.opengion.hayabusa.common.SystemData#FILE_URL 662 */ 663 public void setFileURL( final String url ) { 664 String furl = nval( getRequestParameter( url ),null ); 665 if( furl != null ) { 666 char ch = furl.charAt( furl.length()-1 ); 667 if( ch != '/' && ch != '\\' ) { furl = furl + "/"; } 668 fileURL = StringUtil.urlAppend( fileURL,furl ); 669 } 670// else if( url != null && url.startsWith( "{@" ) ) { 671// String errMsg = "upload では、enctype=\"multipart/form-data\" のため、{@XXXX}形式のパラメータが使えません。" 672// + " fileURL=[" + url + "]" ; 673// throw new HybsSystemException( errMsg ); // 5.7.1.1 (2013/12/13) リクエスト変数が使えないエラー 674// } 675 else { 676// chckReqParam( url,"fileURL" ); // 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェック 677 // 5.9.13.1 (2016/10/21) このチェックがあると既存システムのバージョンアップ時に気が付かずに 678 // 対象画面以外でエラーを発生させてしまう可能性があるので、V5では消しておく 679 } 680 } 681 682 /** 683 * 【TAG】最大転送サイズ(Byte)を指定します(初期値:10485760)。 684 * 685 * @og.tag 686 * 最大転送サイズを指定します。初期値は、10*1024*1024 = 10MB です。 687 * 指定は、Byte 単位で指定します。 688 * 0,またはマイナスを指定することで、制限チェックを外す(=無制限)事ができます。 689 * 690 * @og.rev 3.0.1.1 (2003/03/06) maxPostSize の設定バグ修正。 691 * @og.rev 5.6.5.3 (2013/06/28) コメント追加(0,またはマイナスで無制限) 692 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェックを行う。 693 * 694 * @param maxPS 最大転送サイズ 695 */ 696 public void setMaxPostSize( final String maxPS ) { 697 maxPostSize = nval( getRequestParameter( maxPS ),maxPostSize ); 698 699 chckReqParam( maxPS,"maxPostSize" ); // 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェック 700 } 701 702 /** 703 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 704 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 705 * 706 * @og.tag 707 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 708 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 709 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 710 * この tableId 属性を利用して、メモリ空間を分けます。 711 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 712 * 713 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェックを行う。 714 * 715 * @param id sessionに登録する時の ID 716 */ 717 public void setTableId( final String id ) { 718 tableId = nval( getRequestParameter( id ),tableId ); 719 720 chckReqParam( id,"tableId" ); // 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェック 721 } 722 723 /** 724 * 【TAG】(通常使いません)ファイルを作成するときのファイル名をセットします。 725 * 726 * @og.tag 727 * ファイルを作成するときのファイル名をセットします。 728 * これは、複数同時にアップロードファイル名を変更する時に使用できません。 729 * 通常、アップロードされたファイル名を指定する場合、アップロードするinput タグの 730 * name 属性に指定する名称 + "_NEW" というリクエスト値を同時に送信すれば、 731 * 内部的に関連付けて、ファイル名を更新します。 732 * その場合、クライアントより指定したファイル名は、name属性+"_ORG" という 733 * リクエスト値として取得することが可能になります。 734 * name属性 には、最終的に設定されたファイル名がセットされています。 735 * いずれの値も、{@name属性+"_ORG"} や、{@name属性+"_NEW"}として、 736 * アップロードのオリジナルと変更後のファイル名を取得することが出来ます。 737 * 738 * 5.7.1.2 (2013/12/20) zip 対応 739 * filename 属性に、".zip" の拡張子のファイル名を指定した場合は、アップロードされた一連のファイルを 740 * ZIP圧縮します。これは、アップロード後の処理になります。 741 * ZIP圧縮のオリジナルファイルは、そのまま残ります。 742 * なお、ZIPファイルは、useBackup属性を true に設定しても、無関係に、上書きされます。 743 * 744 * 5.7.4.3 (2014/03/28) filename 属性のリクエスト変数対応 745 * filename 属性のみ、{@XXXX} のリクエスト変数が使えるようにします。 746 * 他のパラメータでは使えません。 747 * これは、multipart/form-data のリクエストでは、パートの分解処理をしないと、リクエスト変数が 748 * 拾えない為、リクエスト変数は、この、upload タグ以降でのみ利用可能でした。 749 * zip対応と関連付けて、filename 属性のみ、利用できるように、MultipartRequest 側の処理に組み込みます。 750 * 751 * @og.rev 3.5.4.2 (2003/12/15) ファイル名を指定できるようにします。 752 * @og.rev 5.7.1.1 (2013/12/13) リクエスト変数が使えないエラーを表示する。 753 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数を使えるようにします。 754 * 755 * @param fname ファイル名 756 */ 757 public void setFilename( final String fname ) { 758 filename = nval( getReservedParameter( fname ),null ); // 予約語のみ処理をします。 759 760// filename = nval( getRequestParameter( fname ),null ); 761 762// if( filename == null && fname != null && fname.startsWith( "{@" ) ) { 763// String errMsg = "upload では、enctype=\"multipart/form-data\" のため、{@XXXX}形式のパラメータが使えません。" 764// + " filename=[" + fname + "]" ; 765// throw new HybsSystemException( errMsg ); // 5.7.1.1 (2013/12/13) リクエスト変数が使えないエラー 766// } 767 } 768 769 /** 770 * 【TAG】DBTableModel作成時に、指定のカラムの"_01"〜"_99"の添え字をレコードとして作成します。 771 * 772 * @og.tag 773 * 現状は、"KEY","VALUE","ISFILE" のカラムに、データを縦持ちで作成しています。 774 * これを、横持で作成しますが、カラムの末尾に、"_01"〜"_99" までの添え字を 775 * 持つ場合は、これをレコードと認識させます。 776 * アンダーバーがない場合は、カラムだけ作成されます。カラム名と同じリクエストがあれば、 777 * すべてのレコードに同じ値がセットされます。 778 * この処理は、columns 属性を設定した場合のみとします。 779 * 780 * @og.rev 5.6.5.2 (2013/06/21) 新規作成 781 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェックを行う。 782 * 783 * @param clms DBTableModel作成時のカラム列(カンマ区切り文字) 784 */ 785 public void setColumns( final String clms ) { 786 columns = nval( getRequestParameter( clms ),columns ); 787 788 chckReqParam( clms,"columns" ); // 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェック 789 } 790 791 /** 792 * 【TAG】ファイルアップロード時に、すでに同名のファイルが存在した場合に、バックアップ処理(renameTo)するかどうか[true/false]を指定します(初期値:false)。 793 * 794 * @og.tag 795 * ファイルアップロード時に、アップロード先に、同名のファイルが存在した場合は、既存機能は、そのまま 796 * 置き換えていましたが、簡易バージョンアップ機能として、useBackup="true" を指定すると、既存のファイルを 797 * リネームして、バックアップファイルを作成します。 798 * バックアップファイルは、アップロードフォルダを基準として、_backup/ファイル名.拡張子_処理時刻のlong値.拡張子 になります。 799 * オリジナルのファイル名(拡張子付)を残したまま、"_処理時刻のlong値" を追加し、さらに、オリジナルの拡張子を追加します。 800 * バックアップファイルの形式は指定できません。 801 * 802 * 初期値は、互換性を持たせるため、false です。 803 * 804 * @og.rev 5.6.5.3 (2013/06/28) 新規作成 805 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェックを行う。 806 * 807 * @param flag ファイルアップロード時に、バックアップ処理(renameTo)するかどうか[true/false]を指定 808 */ 809 public void setUseBackup( final String flag ) { 810 useBackup = nval( getRequestParameter( flag ),useBackup ); 811 812 chckReqParam( flag,"useBackup" ); // 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェック 813 } 814 815 /** 816 * リクエスト変数が使えない事のチェックを行います。 817 * 818 * upload では、enctype="multipart/form-data" のため、{@XXXX}形式のパラメータが使えません。 819 * 5.7.4.3 (2014/03/28) から、filename のみ利用可能としたことで、同様に利用できると 820 * 勘違いするケースに対応する為、すべてのパラメータについてチェックを行います。 821 * ここでは、getRequestParameter( String ) の実行後、すぐに、isNull() 判定を行う事で、 822 * リクエスト変数の存在チェックを行う事にしています。 823 * 824 * @og.rev 5.7.4.3 (2014/03/28) リクエスト変数が使えない事のチェックを行う。 825 * 826 * @param org 引数のオリジナル値 827 * @param key エラーの発生した変数名 828 * @throws HybsSystemException パラメータが使用されていた場合 829 */ 830 private void chckReqParam( final String org,final String key ) { 831 if( isNull() && org != null && org.contains( "{@" ) ) { 832 String errMsg = "upload では、enctype=\"multipart/form-data\" のため、{@XXXX}形式のパラメータが使えません。" 833 + HybsSystem.CR 834 + " " + key + "=[" + org + "]" ; 835 throw new HybsSystemException( errMsg ); // リクエスト変数が使えないエラー 836 } 837 } 838 839 /** 840 * タグの名称を、返します。 841 * 自分自身のクラス名より、自動的に取り出せないため、このメソッドをオーバーライドします。 842 * 843 * @og.rev 4.0.0.0 (2005/01/31) 新規追加 844 * 845 * @return タグの名称 846 */ 847 @Override 848 protected String getTagName() { 849 return "upload" ; 850 } 851 852 /** 853 * このオブジェクトの文字列表現を返します。 854 * 基本的にデバッグ目的に使用します。 855 * 856 * @return このクラスの文字列表現 857 */ 858 @Override 859 public String toString() { 860 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 861 .println( "VERSION" ,VERSION ) 862 .println( "names" ,names ) 863 .println( "ENCODE" ,ENCODE ) 864 .println( "fileURL" ,fileURL ) 865 .println( "filename" ,filename ) 866 .println( "maxPostSize" ,maxPostSize) 867 .println( "tableId" ,tableId ) 868 .println( "columns" ,columns ) // 5.6.5.2 (2013/06/21) 869 .println( "useBackup" ,useBackup ) // 5.6.5.3 (2013/06/28) 870 .println( "Other..." ,getAttributes().getAttribute() ) 871 .fixForm().toString() ; 872 } 873}