diff --git a/help/result.saveas.md b/help/result.saveas.md index 7caabb4..87f22b9 100644 --- a/help/result.saveas.md +++ b/help/result.saveas.md @@ -15,10 +15,12 @@ result.attach("test.xls") +
CallingReturning
Result . saveas ( filename )Result
Result . saveas ( filename , password )Result
+
ParametersTypeDescription
filenameStringThe file name for saving.
passwordStringIf a folder or multi files are attached, you can save all to a named zip with password.
diff --git a/src/efw/file/FileManager.java b/src/efw/file/FileManager.java index 41e4f2b..4912c7a 100644 --- a/src/efw/file/FileManager.java +++ b/src/efw/file/FileManager.java @@ -8,6 +8,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; @@ -128,22 +129,43 @@ else if(f.isDirectory()){//ディレクトリの場合は、すべてのファ * @param fromFilePaths 圧縮対象のファイル配列。 * @param basePath 圧縮ファイルのベースパス。 * @param basePathIsAbs 圧縮対象と圧縮ファイルのベースパスか相対パスかのフラグ。 + * @param password パスワード。 * @throws IOException ファイルアクセスエラー。 */ - public static void zip(String toZipPath, boolean toZipPathIsAbs, String[] fromFilePaths, String basePath, boolean basePathIsAbs) throws IOException{ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void zip(String toZipPath, boolean toZipPathIsAbs, String[] fromFilePaths, String basePath, boolean basePathIsAbs, String password) throws IOException{ //filename is the zip file name, so it is in storage. - ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream( - new FileOutputStream(toZipPathIsAbs?getByAbsolutePath(toZipPath):get(toZipPath)) - ),Charset.forName( - PropertiesManager.getProperty( - PropertiesManager.EFW_ZIP_CHARSET,ZIP_CHARSET - ) - )); - try{ - _zip(zos,fromFilePaths,basePath,basePathIsAbs); - }finally{ - zos.close(); + if (password!=null && !"".equals(password)) { + try{ + Class.forName("net.lingala.zip4j.ZipFile");//もしjar存在しない場合エラーさせるため + Class zip4jUtils = Class.forName("efw.util.Zip4jUtils"); + Method method = zip4jUtils.getDeclaredMethod("zip", + String.class,//toZipPath + boolean.class,//toZipPathIsAbs + String[].class,//fromFilePaths + String.class,//basePath + boolean.class,//basePathIsAbs + String.class//password + ); + method.invoke(null,toZipPath,toZipPathIsAbs,fromFilePaths,basePath,basePathIsAbs,password); + return; + }catch(Exception ex){ + framework.runtimeWLog(ex); + } } + //パスワードなしまたはzip4j失敗の場合、JDKの仕組みでzipする + ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream( + new FileOutputStream(toZipPathIsAbs?getByAbsolutePath(toZipPath):get(toZipPath)) + ),Charset.forName( + PropertiesManager.getProperty( + PropertiesManager.EFW_ZIP_CHARSET,ZIP_CHARSET + ) + )); + try{ + _zip(zos,fromFilePaths,basePath,basePathIsAbs); + }finally{ + zos.close(); + } } /** * ファイルを圧縮する内部関数 diff --git a/src/efw/file/downloadServlet.java b/src/efw/file/downloadServlet.java index 9a43b2b..6f3e1f0 100644 --- a/src/efw/file/downloadServlet.java +++ b/src/efw/file/downloadServlet.java @@ -29,6 +29,7 @@ public final class downloadServlet extends HttpServlet { private static final String EFW_DOWNLOAD_FILE="efw.download.file"; private static final String EFW_DOWNLOAD_ZIP="efw.download.zip"; private static final String EFW_DOWNLOAD_SAVEAS="efw.download.saveas"; + private static final String EFW_DOWNLOAD_PASSWORD="efw.download.password"; private static final String EFW_DOWNLOAD_DELETEAFTERDOWNLOAD="efw.download.deleteafterdownload"; private static final String EFW_DOWNLOAD_ZIPBASEPATH="efw.download.zipBasePath"; private static final String EFW_DOWNLOAD_ISABS="efw.download.isAbs"; @@ -44,12 +45,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response)th String attr_file=(String)sn.getAttribute(EFW_DOWNLOAD_FILE); String attr_zip=(String)sn.getAttribute(EFW_DOWNLOAD_ZIP); String attr_saveas=(String)sn.getAttribute(EFW_DOWNLOAD_SAVEAS); + String attr_password=(String)sn.getAttribute(EFW_DOWNLOAD_PASSWORD); String attr_deleteafterdownload=(String)sn.getAttribute(EFW_DOWNLOAD_DELETEAFTERDOWNLOAD); String attr_zipBasePath=(String)sn.getAttribute(EFW_DOWNLOAD_ZIPBASEPATH); String attr_isAbs=(String)sn.getAttribute(EFW_DOWNLOAD_ISABS); sn.removeAttribute(EFW_DOWNLOAD_FILE); sn.removeAttribute(EFW_DOWNLOAD_ZIP); sn.removeAttribute(EFW_DOWNLOAD_SAVEAS); + sn.removeAttribute(EFW_DOWNLOAD_PASSWORD); sn.removeAttribute(EFW_DOWNLOAD_DELETEAFTERDOWNLOAD); sn.removeAttribute(EFW_DOWNLOAD_ZIPBASEPATH); sn.removeAttribute(EFW_DOWNLOAD_ISABS); @@ -65,7 +68,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response)th tmp_zip=zipFile.getName(); attr_file=zipFile.getName(); //ダウンロード時の一時ファイルは相対パスで保存する - FileManager.zip(tmp_zip,false, tmp_files, attr_zipBasePath,"true".equals(attr_isAbs)); + FileManager.zip(tmp_zip,false, tmp_files, attr_zipBasePath,"true".equals(attr_isAbs),attr_password); if(attr_saveas==null||"".equals(attr_saveas)){ attr_saveas="attachment.zip"; @@ -84,7 +87,8 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response)th } response.setContentType("application/octet-stream"); - response.setHeader("Content-Disposition","attachment; filename=\""+java.net.URLEncoder.encode(attr_saveas, framework.SYSTEM_CHAR_SET)+"\""); + response.setHeader("Content-Disposition","attachment; filename=\"" + +java.net.URLEncoder.encode(attr_saveas, framework.SYSTEM_CHAR_SET).replace("+", "%20")+"\""); Cookie ck=new Cookie("efw_Downloaded","OK"); ck.setPath("/"); response.addCookie(ck); diff --git a/src/efw/framework.java b/src/efw/framework.java index a5a3cc1..547d40d 100644 --- a/src/efw/framework.java +++ b/src/efw/framework.java @@ -33,7 +33,7 @@ public final class framework { /** * バージョンを表す。 */ - public static final String version="4.07.022";// change it when releasing jar. + public static final String version="4.07.023";// change it when releasing jar. /** * webHome */ @@ -867,7 +867,7 @@ public static void runtimeWLog(String info) { */ public static void runtimeWLog(Exception ex) { if (LogManager.getLogger().getLevel().intValue()<=Level.WARNING.intValue()) { - runtime(Level.SEVERE,getUsefulInfoFromException(ex)); + runtime(Level.WARNING,getUsefulInfoFromException(ex)); } } /** diff --git a/src/efw/resources/elfinder/elfinder_achive.js b/src/efw/resources/elfinder/elfinder_achive.js index ca8fd15..91f4774 100644 --- a/src/efw/resources/elfinder/elfinder_achive.js +++ b/src/efw/resources/elfinder/elfinder_achive.js @@ -21,7 +21,7 @@ elfinder_archive.fire = function(params) { files.push(cwdFile); } //圧縮する - Packages.efw.file.FileManager.zip(newFile,isAbs, files, parentPath,isAbs); + Packages.efw.file.FileManager.zip(newFile,isAbs, files, parentPath,isAbs, null); //圧縮ファイル情報を取得する var target=(new Record([file.get(newFile,true)])) .map({ diff --git a/src/efw/resources/server/efw.server.js b/src/efw/resources/server/efw.server.js index 161cfe8..ec19bb1 100644 --- a/src/efw/resources/server/efw.server.js +++ b/src/efw/resources/server/efw.server.js @@ -306,6 +306,9 @@ EfwServer.prototype.fire = function(event, requestParams) { var tmpsaveas = download.saveas; if (tmpsaveas == null) tmpsaveas = ""; + var tmppassword=download.password; + if (tmppassword == null) + tmppassword = ""; var tmpzipBasePath =download.zipBasePath; if (tmpzipBasePath == null) tmpzipBasePath = ""; @@ -320,6 +323,7 @@ EfwServer.prototype.fire = function(event, requestParams) { session.set("efw.download.deleteafterdownload", tmpdeleteafterdownload); session.set("efw.download.saveas", tmpsaveas); + session.set("efw.download.password", tmppassword); session.set("efw.download.zipBasePath", tmpzipBasePath); session.set("efw.download.isAbs", tmpisAbs); diff --git a/src/efw/resources/server/efw.server.result.js b/src/efw/resources/server/efw.server.result.js index 8314649..4fd6684 100644 --- a/src/efw/resources/server/efw.server.result.js +++ b/src/efw/resources/server/efw.server.result.js @@ -99,7 +99,7 @@ Result.prototype.concat = function(result) { if (result.actions.download){ if (result.actions.download.zip)this.attach(result.actions.download.zip,result.actions.download.zipBasePath); if (result.actions.download.file)this.attach(result.actions.download.file,result.actions.download.zipBasePath); - if (result.actions.download.saveas)this.saveas(result.actions.download.saveas); + if (result.actions.download.saveas)this.saveas(result.actions.download.saveas,result.actions.download.password); if (result.actions.download.deleteafterdownload)this.deleteAfterDownload(); } if (result.actions.alert)this.alert(result.actions.alert,result.actions.alertTitle); @@ -241,11 +241,13 @@ Result.prototype.attach = function(path,zipBasePath,isAbs) { * The function to set the file name for saving . * * @param {String} filename: required
+ * @param {String} password: optional
* @returns {Result} */ -Result.prototype.saveas = function(filename) { +Result.prototype.saveas = function(filename,password) { if (!this.actions.download)this.actions.download={}; this.actions.download.saveas=filename; + this.actions.download.password=password; return this; }; diff --git a/src/efw/util/Zip4jUtils.java b/src/efw/util/Zip4jUtils.java new file mode 100644 index 0000000..3f2987d --- /dev/null +++ b/src/efw/util/Zip4jUtils.java @@ -0,0 +1,73 @@ +package efw.util; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; + +import efw.file.FileManager; +import efw.properties.PropertiesManager; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.model.enums.EncryptionMethod; + +public final class Zip4jUtils { + + private static final String ZIP_CHARSET="UTF-8"; + + /** + * ファイルを圧縮する。 + * @param toZipPath 圧縮後のファイルパス。 + * @param toZipPathIsAbs 圧縮後のファイルパスは絶対パスか相対パスかのフラグ。 + * @param fromFilePaths 圧縮対象のファイル配列。 + * @param basePath 圧縮ファイルのベースパス。 + * @param basePathIsAbs 圧縮対象と圧縮ファイルのベースパスか相対パスかのフラグ。 + * @param password パスワード。 + * @throws IOException ファイルアクセスエラー。 + */ + public static void zip(String toZipPath, boolean toZipPathIsAbs, String[] fromFilePaths, String basePath, boolean basePathIsAbs, String password) throws IOException{ + ZipParameters params = new ZipParameters(); + File flBase=basePathIsAbs?FileManager.getByAbsolutePath(basePath):FileManager.get(basePath); + params.setDefaultFolderPath(flBase.getAbsolutePath()); + ZipFile zos = new ZipFile(toZipPathIsAbs?FileManager.getByAbsolutePath(toZipPath):FileManager.get(toZipPath)); + zos.setCharset(Charset.forName( + PropertiesManager.getProperty( + PropertiesManager.EFW_ZIP_CHARSET,ZIP_CHARSET + ) + )); + if(password!=null && !"".equals(password)) { + params.setEncryptFiles(true); + params.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD); + char[] pass = password.toCharArray(); + zos.setPassword(pass); + } + try{ + _zip(zos,fromFilePaths,basePath,basePathIsAbs,params); + }finally{ + zos.close(); + } + } + /** + * ファイルを圧縮する内部関数 + * @param zos + * @param paths + * @param basePath + * @param isAbs + * @throws IOException + */ + private static void _zip(ZipFile zos,String[] paths, String basePath, boolean isAbs,ZipParameters params) throws IOException { + for (String path : paths) { + File fl=isAbs?FileManager.getByAbsolutePath(path):FileManager.get(path); + if(fl.isDirectory()){ + File[] f = isAbs?FileManager.getListByAbsolutePath(path):FileManager.getList(path); + String[] paths2=new String[f.length]; + for(int i=0;i + * @param {String} password: optional
* @returns {Result} */ -Result.prototype.saveas = function(filename) { +Result.prototype.saveas = function(filename,password) { if (!this.actions.download)this.actions.download={}; this.actions.download.saveas=filename; + this.actions.download.password=password; return this; }; diff --git a/src4jakarta/efw/util/Zip4jUtils.java b/src4jakarta/efw/util/Zip4jUtils.java new file mode 100644 index 0000000..3f2987d --- /dev/null +++ b/src4jakarta/efw/util/Zip4jUtils.java @@ -0,0 +1,73 @@ +package efw.util; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; + +import efw.file.FileManager; +import efw.properties.PropertiesManager; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.model.enums.EncryptionMethod; + +public final class Zip4jUtils { + + private static final String ZIP_CHARSET="UTF-8"; + + /** + * ファイルを圧縮する。 + * @param toZipPath 圧縮後のファイルパス。 + * @param toZipPathIsAbs 圧縮後のファイルパスは絶対パスか相対パスかのフラグ。 + * @param fromFilePaths 圧縮対象のファイル配列。 + * @param basePath 圧縮ファイルのベースパス。 + * @param basePathIsAbs 圧縮対象と圧縮ファイルのベースパスか相対パスかのフラグ。 + * @param password パスワード。 + * @throws IOException ファイルアクセスエラー。 + */ + public static void zip(String toZipPath, boolean toZipPathIsAbs, String[] fromFilePaths, String basePath, boolean basePathIsAbs, String password) throws IOException{ + ZipParameters params = new ZipParameters(); + File flBase=basePathIsAbs?FileManager.getByAbsolutePath(basePath):FileManager.get(basePath); + params.setDefaultFolderPath(flBase.getAbsolutePath()); + ZipFile zos = new ZipFile(toZipPathIsAbs?FileManager.getByAbsolutePath(toZipPath):FileManager.get(toZipPath)); + zos.setCharset(Charset.forName( + PropertiesManager.getProperty( + PropertiesManager.EFW_ZIP_CHARSET,ZIP_CHARSET + ) + )); + if(password!=null && !"".equals(password)) { + params.setEncryptFiles(true); + params.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD); + char[] pass = password.toCharArray(); + zos.setPassword(pass); + } + try{ + _zip(zos,fromFilePaths,basePath,basePathIsAbs,params); + }finally{ + zos.close(); + } + } + /** + * ファイルを圧縮する内部関数 + * @param zos + * @param paths + * @param basePath + * @param isAbs + * @throws IOException + */ + private static void _zip(ZipFile zos,String[] paths, String basePath, boolean isAbs,ZipParameters params) throws IOException { + for (String path : paths) { + File fl=isAbs?FileManager.getByAbsolutePath(path):FileManager.get(path); + if(fl.isDirectory()){ + File[] f = isAbs?FileManager.getListByAbsolutePath(path):FileManager.getList(path); + String[] paths2=new String[f.length]; + for(int i=0;i