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 javax.mail 関連のエラーが発生したと?
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 * ※ ?レクトリの作?に失敗した?合?RuntimeException ?throw されます?
182 *
183 * @param dir セーブするディレクトリ。null の場合?、セーブしな??
184 * @param newNm セーブするファイル?null の場合??重?された添付ファイル?
185 * @param fno 添付ファイルの番号
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 }