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 }