root/as3/Thread/trunk/src/org/libspark/thread/threads/net/FileUploadThread.as

リビジョン 942, 11.7 kB (コミッタ: yossy, コミット時期: 2 年 前)

Thread: FileUploadThread?DataEvent?.data の内容を受け取れるように修正

Line 
1 /*
2  * ActionScript Thread Library
3  *
4  * Licensed under the MIT License
5  *
6  * Copyright (c) 2008 BeInteractive! (www.be-interactive.org) and
7  *                    Spark project  (www.libspark.org)
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25  * THE SOFTWARE.
26  *
27  */
28 package org.libspark.thread.threads.net
29 {
30         import flash.errors.IOError;
31         import flash.events.DataEvent;
32         import flash.events.Event;
33         import flash.events.IOErrorEvent;
34         import flash.events.ProgressEvent;
35         import flash.events.SecurityErrorEvent;
36         import flash.net.FileReference;
37         import flash.net.URLRequest;
38        
39         import org.libspark.thread.Thread;
40         import org.libspark.thread.utils.IProgress;
41         import org.libspark.thread.utils.IProgressNotifier;
42         import org.libspark.thread.utils.Progress;
43        
44         /**
45          * FileReference を用いてファイルをアップロードするためのスレッドです.
46          *
47          * <p>このスレッドを開始すると、与えられた URLRequest を用いてアップロード処理を開始し、
48          * ロードが完了 (Event.COMPLETE) するとスレッドが終了します。</p>
49          *
50          * <p>join メソッドを用いると、簡単にロード待ちをすることができます。</p>
51          *
52          * <p>ロード中にエラーが発生した場合は、以下の例外がスローされます。
53          * これらの例外は、このスレッドを開始したスレッド(親スレッド)で捕捉する事が出来ます。</p>
54          *
55          * <ul>
56          * <li>flash.events.IOErrorEvent.IO_ERROR: flash.errors.IOError</li>
57          * <li>flash.events.SecurityErrorEvent.SECURITY_ERROR: SecurityError</li>
58          * </ul>
59          *
60          * @author      seagirl
61          * @author      yossy:beinteractive
62          */
63         public class FileUploadThread extends Thread implements IProgressNotifier
64                 {
65                         /**
66                          * 新しい FileReferenceThread クラスのインスタンスを生成します.
67                          *
68                          * @param request ロード対象となる URLRequest
69                          * @param fileReference ロードに使用する FileReference 。省略もしくは null の場合、新たに作成した FileReference を使用します
70                          * @param       updateDataFieldName     アップロードの POST に使用するフィールド名。詳しくは FileReference.upload を参照してください
71                          * @param       testUpload      アップロードのテストをするかどうか。詳しくは FileReference.upload を参照してください
72                          * @param       waitCompleteData        DataEvent.UPLOAD_COMPLETE_DATA を待ってスレッドを終了するのであれば true そうでなければ false
73                          * @param       doBrowse        アップロードの前に browse メソッドを呼び出すのであれば true、そうでなければ false
74                          * @param       typeFilter      doBrowse が true の場合、拡張子フィルタ。詳しくは FileReference.browse を参照してください
75                          */
76                         public function FileUploadThread(request:URLRequest, fileReference:FileReference = null, uploadDataFieldName:String = "Filedata", testUpload:Boolean = false, waitCompleteData:Boolean = false, doBrowse:Boolean = true, typeFilter:Array = null)
77                         {
78                                 _request = request;
79                                 _fileReference = fileReference != null ? fileReference : new FileReference();
80                                 _uploadDataFieldName = uploadDataFieldName;
81                                 _testUpload = testUpload;
82                                 _waitCompleteData = waitCompleteData;
83                                 _doBrowse = doBrowse;
84                                 _typeFilter = typeFilter;
85                                 _progress = new Progress();
86                                 _data = null;
87                         }
88                        
89                         private var _request:URLRequest;
90                         private var _fileReference:FileReference;
91                         private var _uploadDataFieldName:String;
92                         private var _testUpload:Boolean;
93                         private var _waitCompleteData:Boolean;
94                         private var _doBrowse:Boolean;
95                         private var _typeFilter:Array;
96                         private var _progress:Progress;
97                         private var _data:String;
98                        
99                         /**
100                          * ロード対象となる URLRequest を返します.
101                          */
102                         public function get request():URLRequest
103                         {
104                                 return _request;
105                         }
106                        
107                         /**
108                          * ロードに使用する FileReference を返します.
109                          */
110                         public function get fileReference():FileReference
111                         {
112                                 return _fileReference;
113                         }
114                        
115                         /**
116                          * アップロードの POST に使用するフィールド名。詳しくは FileReference.upload を参照してください.
117                          */
118                         public function get uploadDataFieldName():String
119                         {
120                                 return _uploadDataFieldName;
121                         }
122                        
123                         /**
124                          * @private
125                          */
126                         public function set uploadDataFieldName(value:String):void
127                         {
128                                 _uploadDataFieldName = value;
129                         }
130                        
131                         /**
132                          * アップロードのテストをするかどうか。詳しくは FileReference.upload を参照してください.
133                          */
134                         public function get testUpload():Boolean
135                         {
136                                 return _testUpload;
137                         }
138                        
139                         /**
140                          * @private
141                          */
142                         public function set testUpload(value:Boolean):void
143                         {
144                                 _testUpload = value;
145                         }
146                        
147                         /**
148                          * DataEvent.UPLOAD_COMPLETE_DATA を待ってスレッドを終了するのであれば true そうでなければ false を設定します.
149                          */
150                         public function get waitCompleteData():Boolean
151                         {
152                                 return _waitCompleteData;
153                         }
154                        
155                         /**
156                          * @private
157                          */
158                         public function set waitCompleteData(value:Boolean):void
159                         {
160                                 _waitCompleteData = value;
161                         }
162                        
163                         /**
164                          * waitCompleteData が true の場合に、DataEvent で受け取ることのできる data プロパティの内容を返します.
165                          *
166                          * @see #waitCompleteData
167                          */
168                         public function get data():String
169                         {
170                                 return _data;
171                         }
172                        
173                         /**
174                          * アップロードの前に browse メソッドを呼び出すのであれば true、そうでなければ false を設定します.
175                          */
176                         public function get doBrowse():Boolean
177                         {
178                                 return _doBrowse;
179                         }
180                        
181                         /**
182                          * @private
183                          */
184                         public function set doBrowse(value:Boolean):void
185                         {
186                                 _doBrowse = value;
187                         }
188                        
189                         /**
190                          * doBrowse が true の場合、拡張子フィルタ。詳しくは FileReference.browse を参照してください.
191                          */
192                         public function get typeFilter():Array
193                         {
194                                 return _typeFilter;
195                         }
196                        
197                         /**
198                          * @private
199                          */
200                         public function set typeFilter(value:Array):void
201                         {
202                                 _typeFilter = value;
203                         }
204                        
205                         /**
206                          * @inheritDoc
207                          */
208                         public function get progress():IProgress
209                         {
210                                 return _progress;
211                         }
212                        
213                         /**
214                          * アップロード処理をキャンセルします.
215                          */
216                         public function cancel():void
217                         {
218                                 // 割り込みをかける
219                                 interrupt();
220                         }
221                        
222                         /**
223                          * 実行
224                          *
225                          * @private
226                          */
227                         override protected function run():void
228                         {
229                                 // browse メソッド呼び出しが要求されている場合
230                                 if (doBrowse) {
231                                         // 呼び出す
232                                         browse();
233                                 }
234                                 else {
235                                         // そうでなければアップロード
236                                         upload();
237                                 }
238                         }
239                        
240                         /**
241                          * browse メソッド呼び出し
242                          *
243                          * @private
244                          */
245                         private function browse():void
246                         {
247                                 // browse 呼び出し
248                                 if (fileReference.browse(typeFilter)) {
249                                         // 成功の場合イベントハンドラ設定
250                                         event(fileReference, Event.SELECT, browseSelectHandler);
251                                         event(fileReference, Event.CANCEL, browseCancelHandler);
252                                 }
253                                 else {
254                                         // 失敗の場合キャンセルと同等の処理をする
255                                         browseCancelHandler(null);
256                                 }
257                         }
258                        
259                         /**
260                          * browse 選択ハンドラ
261                          *
262                          * @private
263                          */
264                         private function browseSelectHandler(e:Event):void
265                         {
266                                 // 選択されたらアップロードする
267                                 upload();
268                         }
269                        
270                         /**
271                          * browse キャンセルハンドラ
272                          *
273                          * @private
274                          */
275                         private function browseCancelHandler(e:Event):void
276                         {
277                                 // とりあえず開始したことにして
278                                 _progress.start(0);
279                                 // すぐキャンセル
280                                 _progress.cancel();
281                                 // して終わり
282                         }
283                        
284                         /**
285                          * アップロード
286                          *
287                          * @private
288                          */
289                         private function upload():void
290                         {
291                                 // イベントハンドラを設定
292                                 // Note: イベントハンドラを設定した場合、自動的に wait がかかる
293                                 events();
294                                
295                                 // 割り込みハンドラを設定
296                                 interrupted(interruptedHandler);
297                                
298                                 // アップロード開始
299                                 fileReference.upload(request, uploadDataFieldName, testUpload);
300                         }
301                        
302                         /**
303                          * イベントハンドラの登録
304                          *
305                          * @private
306                          */
307                         private function events():void
308                         {
309                                 if (waitCompleteData) {
310                                         event(fileReference, DataEvent.UPLOAD_COMPLETE_DATA, completeHandler);
311                                 }
312                                 else {
313                                         event(fileReference, Event.COMPLETE, completeHandler);
314                                 }
315                                 event(fileReference, ProgressEvent.PROGRESS, progressHandler);
316                                 event(fileReference, IOErrorEvent.IO_ERROR, ioErrorHandler);
317                                 event(fileReference, SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
318                         }
319                        
320                         /**
321                          * まだ開始を通知していなければ通知する
322                          *
323                          * @private
324                          */
325                         private function notifyStartIfNeeded(total:Number):void
326                         {
327                                 if (!_progress.isStarted) {
328                                         _progress.start(total);
329                                 }
330                         }
331                        
332                         /**
333                          * ProgressEvent.PROGRESS ハンドラ
334                          *
335                          * @private
336                          */
337                         private function progressHandler(e:ProgressEvent):void
338                         {
339                                 // 必要であれば開始を通知
340                                 notifyStartIfNeeded(e.bytesTotal);
341                                
342                                 // 進捗を通知
343                                 _progress.progress(e.bytesLoaded);
344                                
345                                 // 割り込みハンドラを設定
346                                 interrupted(interruptedHandler);
347                                
348                                 // 再びイベント待ち
349                                 events();
350                         }
351                        
352                         /**
353                          * Event.COMPLETE ハンドラ
354                          *
355                          * @private
356                          */
357                         private function completeHandler(e:Event):void
358                         {
359                                 if (e is DataEvent) {
360                                         _data = DataEvent(e).data;
361                                 }
362                                
363                                 // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
364                                 notifyStartIfNeeded(0);
365                                
366                                 // 完了を通知
367                                 _progress.complete();
368                                
369                                 // ここでスレッド終了
370                         }
371                        
372                         /**
373                          * IOErrorEvent.IO_ERROR ハンドラ
374                          *
375                          * @private
376                          */
377                         private function ioErrorHandler(e:IOErrorEvent):void
378                         {
379                                 // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
380                                 notifyStartIfNeeded(0);
381                                
382                                 // 失敗を通知
383                                 _progress.fail();
384                                
385                                 // IOError をスロー
386                                 throw new IOError(e.text);
387                         }
388                        
389                         /**
390                          * SecurityErrorEvent.SECURITY_ERROR ハンドラ
391                          *
392                          * @private
393                          */
394                         private function securityErrorHandler(e:SecurityErrorEvent):void
395                         {
396                                 // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
397                                 notifyStartIfNeeded(0);
398                                
399                                 // 失敗を通知
400                                 _progress.fail();
401                                
402                                 // SecurityError をスロー
403                                 throw new SecurityError(e.text);
404                         }
405                        
406                         /**
407                          * 割り込みハンドラ
408                          *
409                          * @private
410                          */
411                         private function interruptedHandler():void
412                         {
413                                 // 必要であれば開始を通知 (問題が発生しなければ通常 progressHandler で通知される)
414                                 notifyStartIfNeeded(0);
415                                
416                                 // アップロードをキャンセル
417                                 fileReference.cancel();
418                                
419                                 // キャンセルを通知
420                                 _progress.cancel();
421                         }
422                 }
423 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。