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 */ 016 package org.opengion.fukurou.mail; 017 018 import org.opengion.fukurou.util.Closer ; 019 020 import javax.mail.MessagingException; 021 import javax.mail.Part; 022 import javax.mail.BodyPart; 023 import javax.mail.Multipart; 024 import java.io.File; 025 import java.io.InputStream; 026 import java.io.FileOutputStream; 027 import java.io.IOException; 028 import java.util.List; 029 import java.util.ArrayList; 030 import java.util.Set; 031 import java.util.HashSet; 032 033 /** 034 * メール添付ファイル処?ラス 035 * 036 * こ?クラスは、添付ファイルを??るため?クラスです? 037 * 添付ファイルは、?ルチパートに含まれて?為、?帰?探す?があります? 038 * 039 * @version 4.0 040 * @author Kazuhiko Hasegawa 041 * @since JDK5.0, 042 */ 043 public class MailAttachFiles { 044 private final List<Part> files ; 045 private final String[] names ; 046 047 /** 048 * ?ォルトコンストラクター 049 * 050 * ?変数の初期化を行います? 051 * 052 * @param part Partオブジェク? 053 */ 054 public MailAttachFiles( final Part part ) { 055 files = new ArrayList<Part>(); 056 names = makeNames( part ); 057 } 058 059 /** 060 * 添付ファイルの名称を文字?配?として求めます? 061 * 062 * @return 添付ファイルの名称を文字?配? 063 */ 064 public String[] getNames() { 065 String[] rtn = null ; 066 067 if( names != null ) { rtn = names.clone(); } 068 069 return rtn ; 070 } 071 072 /** 073 * 添付ファイルの名称を文字?配?として求めます? 074 * 075 * こ?処??中で、添付ファイルを持つ Part を見つけて?配?(List)に登録します? 076 * ファイル名が未??場合??noNameFile" + i + ".tmp" と?ファイル名をつけます? 077 * i は、添付ファイルの連番です? 078 * また?同?付ファイル名が存在する場合???に添付ファイルの連番を付加して? 079 * ファイル名としてユニ?ク化します? 080 * 081 * @og.rev 4.3.3.5 (2008/11/08) 日本語添付ファイルが??きるように修正 082 * 083 * @param part Partオブジェク? 084 * 085 * @return 添付ファイルの名称を文字?配? 086 */ 087 private String[] makeNames( final Part part ) { 088 final String[] nms; 089 try { 090 Set<String> set = new HashSet<String>(); 091 092 fileSearch( part ); 093 nms = new String[files.size()]; 094 for( int i=0; i<nms.length; i++ ) { 095 // String name = ((Part)files.get(i)).getFileName(); 096 String name = (files.get(i)).getFileName(); 097 if( name == null ) { // message か?ファイル名未??ケース 098 nms[i] = "noNameFile" + i + ".tmp" ; 099 } 100 // else { 101 // // encode-word の =? の前にはスペ?スが?? 102 // StringBuilder buf = new StringBuilder( name ); 103 // int pos = buf.indexOf( "?==?" ); // ?ード?終?開始が連結して?? 104 // // 先?でなく?かつ開始記号が含まれて?? 105 // while( pos > 0 ) { 106 // buf.insert( pos+2," " ); 107 // pos = buf.indexOf( "?==?",pos+4 ); 108 // } 109 // } 110 // 4.3.3.5 (2008/11/08) 日本語添付ファイルが??きるように修正 111 else { 112 nms[i] = MailMessage.mimeDecode( name ); 113 } 114 115 // 重?ェ? 116 if( !set.add( nms[i] ) ) { 117 nms[i] = i + "_" + nms[i] ; // 重?に名称変更します? 118 } 119 } 120 } 121 catch( MessagingException ex ) { 122 String errMsg = "メ?ージ??のハンドリングに失敗しました? 123 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 124 throw new RuntimeException( errMsg,ex ); 125 } 126 // catch( UnsupportedEncodingException ex ) { 127 // String errMsg = "?スト情報の?ードに失敗しました? ; 128 // throw new RuntimeException( errMsg,ex ); 129 // } 130 catch( IOException ex ) { 131 String errMsg = "?スト情報の取り出しに失敗しました? 132 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 133 throw new RuntimeException( errMsg,ex ); 134 } 135 return nms; 136 } 137 138 /** 139 * 添付ファイルが存在するかど?をサーチします? 140 * 141 * 添付ファイルは、?ルチパートで?されると、?帰?検索する?が 142 * 出てきます?こ?メソ?では、?帰?ファイルかど?を検索し? 143 * ファイルであれば、?部変数(List)に追?add)して?ます? 144 * 145 * @param part Partオブジェク? 146 * 147 * @return 再帰検索終?true 148 * @throws MessagingException 149 * @throws IOException 150 * 151 */ 152 private boolean fileSearch( final Part part ) throws MessagingException ,IOException { 153 if( part.isMimeType( "multipart/*" ) ) { 154 Multipart mpt = (Multipart)part.getContent(); 155 156 int count = mpt.getCount(); 157 for(int i = 0; i < count; i++) { 158 BodyPart bpt = mpt.getBodyPart(i); 159 fileSearch( bpt ); 160 } 161 } 162 else { 163 if( part.isMimeType( "message/*" ) || 164 part.getFileName() != null || 165 Part.INLINE.equalsIgnoreCase( part.getDisposition() ) ) { 166 files.add( part ); 167 } 168 } 169 return true; 170 } 171 172 /** 173 * 添付ファイルを指定?フォル?セーブします? 174 * 175 * ?変数List の 添付ファイルを持つ Part につ?、ファイルを抜出し? 176 * ???レクトリに保存して?ます? 177 * ファイル名?、基本?添付ファイル名そのも?ですが? 178 * 同?称の添付ファイルが?登録されて?場合?、その重?ァイルの番号? 179 * 頭につけ?番号 + "_" + 添付ファイル?として、ユニ?ク化します? 180 * 181 * @param dir セーブするディレクトリ。null の場合?、セーブしな?? 182 * @param newNm セーブするファイル?null の場合??重?された添付ファイル? 183 * @param fno 添付ファイルの番号 184 * 185 * @throws RuntimeException 186 */ 187 public void saveFileName( final String dir, final String newNm, final int fno ) { 188 if( dir == null ) { return ; } // ファイルをセーブしな?? 189 190 File fileDir = new File( dir ); 191 if( !fileDir.exists() ) { 192 boolean isOk = fileDir.mkdirs(); 193 if( ! isOk ) { 194 String errMsg = "?レクトリの作?に失敗しました?" + dir + "]"; 195 throw new RuntimeException( errMsg ); 196 } 197 } 198 199 String newName = ( newNm != null ) ? newNm : names[fno] ; 200 201 InputStream input = null; 202 FileOutputStream output = null; 203 204 try { 205 Part prt = files.get( fno ); 206 input = prt.getInputStream(); 207 output = new FileOutputStream( new File( fileDir,newName ) ); 208 byte[] buf = new byte[1024]; 209 int len; 210 while( (len = input.read(buf)) != -1 ) { 211 output.write( buf,0,len ); 212 } 213 } 214 catch( MessagingException ex ) { 215 String errMsg = "メ?ージオブジェクト?操作中にエラーが発生しました? 216 + "dir=[" + dir + "], file=[" + newName + "], No=[" + fno + "]" 217 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 218 throw new RuntimeException( errMsg,ex ); 219 } 220 catch( IOException ex ) { 221 String errMsg = "添付ファイルの取り扱?にエラーが発生しました? 222 + "dir=[" + dir + "], file=[" + newName + "], No=[" + fno + "]" 223 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 224 throw new RuntimeException( errMsg,ex ); 225 } 226 finally { 227 Closer.ioClose( output ); 228 Closer.ioClose( input ); 229 } 230 } 231 }