OSDN Git Service

https://osdn.net/cvs/view/gokigen/MeMoMa/ から コピーしてくる。(+API27でビルドできるよう、少し調整。)
[gokigen/MeMoMa.git] / app / src / main / java / jp / sourceforge / gokigen / memoma / fileio / MeMoMaFileImportCsvProcess.java
1 package jp.sourceforge.gokigen.memoma.fileio;
2
3 import java.io.BufferedReader;
4 import java.io.FileReader;
5
6 import android.app.ProgressDialog;
7 import android.content.Context;
8 import android.content.SharedPreferences;
9 import android.os.AsyncTask;
10 import android.preference.PreferenceManager;
11 import android.util.Log;
12
13 import jp.sourceforge.gokigen.memoma.Main;
14 import jp.sourceforge.gokigen.memoma.R;
15 import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder;
16
17 /**
18  *  データをファイルに保存するとき用 アクセスラッパ (非同期処理を実行)
19  *  
20  *  AsyncTask
21  *    MeMoMaObjectHolder : 実行時に渡すクラス(Param)
22  *    Integer    : 途中経過を伝えるクラス(Progress)
23  *    String     : 処理結果を伝えるクラス(Result)
24  *    
25  * @author MRSa
26  *
27  */
28 public class MeMoMaFileImportCsvProcess extends AsyncTask<MeMoMaObjectHolder, Integer, String> implements MeMoMaFileSavingProcess.ISavingStatusHolder, MeMoMaFileSavingProcess.IResultReceiver
29 {       
30         private Context parent = null;
31         private IResultReceiver receiver = null;
32         private ExternalStorageFileUtility fileUtility = null;
33         private String targetFileName = null;
34     private String fileSavedResult = "";
35         private ProgressDialog importingDialog = null;
36
37         private String backgroundUri = null;
38         private String userCheckboxString = null;
39         
40         /**
41          *   コンストラクタ
42          */
43     public MeMoMaFileImportCsvProcess(Context context, ExternalStorageFileUtility utility,  IResultReceiver resultReceiver, String fileName)
44     {
45         parent = context;
46         receiver = resultReceiver;
47         fileUtility = utility;
48         targetFileName = fileName;
49
50         //  プログレスダイアログ(「データインポート中...」)を表示する。
51         importingDialog = new ProgressDialog(context);
52         importingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
53         importingDialog.setMessage(context.getString(R.string.dataImporting));
54         importingDialog.setIndeterminate(true);
55         importingDialog.setCancelable(false);
56         importingDialog.show();
57
58         //  設定読み出し用...あらかじめ、UIスレッドで読みだしておく。         
59         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
60         backgroundUri = preferences.getString("backgroundUri","");
61         userCheckboxString = preferences.getString("userCheckboxString","");
62     }
63         
64     /**
65      *  非同期処理実施前の前処理
66      * 
67      */
68     @Override
69     protected void onPreExecute()
70     {
71     }
72
73     /**
74      *    1レコード分のデータを読み込む。 
75      * 
76      * @param buf
77      * @return
78      */
79     private String readRecord(BufferedReader buf )
80     {
81         String oneRecord = null;
82         try
83         {
84                 String oneLine = buf.readLine();
85             while (oneLine != null)
86             {
87                 oneRecord = (oneRecord == null) ? oneLine : oneRecord + oneLine;
88                 if (oneRecord.indexOf(",;!<_$") > 0)
89                 {
90                         // レコード末尾が見つかったので break する。
91                         break;
92                 }
93                 // 次の行を読みだす。
94                 oneLine = buf.readLine();
95             }
96         }
97         catch (Exception ex)
98         {
99             //
100                 Log.v(Main.APP_IDENTIFIER, "CSV:readRecord() ex : " + ex.toString());
101                 oneRecord = null;
102         }
103         return (oneRecord);
104     }
105
106     /**
107      *   1レコード分のデータを区切る
108      * 
109      * 
110      * @param dataLine
111      */
112     private void parseRecord(String dataLine,  MeMoMaObjectHolder objectHolder)
113     {
114         int detailIndex = 0;
115         int userCheckIndexTrue = 0;
116         int userCheckIndexFalse = 0;
117         int nextIndex = 0;
118         String label = "";
119         String detail = "";
120         boolean userChecked = false;
121         try
122         {
123             detailIndex = dataLine.indexOf("\",\"");
124             if (detailIndex < 0)
125             {
126                 Log.v(Main.APP_IDENTIFIER, "parseRecord() : label wrong : " + dataLine);
127                 return;
128             }
129             label = dataLine.substring(1, detailIndex);
130             userCheckIndexTrue = dataLine.indexOf("\",True,", detailIndex);
131             userCheckIndexFalse = dataLine.indexOf("\",False,", detailIndex);
132             if (userCheckIndexFalse > detailIndex)
133             {
134                 //
135                 detail = dataLine.substring(detailIndex + 3, userCheckIndexFalse);
136                 userChecked = false;
137                 nextIndex = userCheckIndexFalse + 8; // 8は、 ",False, を足した数
138             }
139             else if (userCheckIndexTrue > detailIndex)
140             {
141                 //
142                 detail = dataLine.substring(detailIndex + 3, userCheckIndexTrue);
143                 userChecked = true;
144                 nextIndex = userCheckIndexTrue + 7; // 7は、 ",True,  を足した数
145             }
146             else // if ((userCheckIndexTrue <= detailIndex)&&(userCheckIndexFalse <= detailIndex))
147             {
148                 Log.v(Main.APP_IDENTIFIER, "parseRecord() : detail wrong : " + dataLine);
149                 return;                 
150             }
151             
152             //  残りのデータを切り出す。
153             String[] datas = (dataLine.substring(nextIndex)).split(",");
154             if (datas.length < 6)
155             {
156                 Log.v(Main.APP_IDENTIFIER, "parseRecord() : data size wrong : " + datas.length);
157                 return;
158             }
159             int drawStyle = Integer.parseInt(datas[0]);
160             String paintStyle = datas[1];
161             float centerX = Float.parseFloat(datas[2]);
162             float centerY = Float.parseFloat(datas[3]);
163             float width = Float.parseFloat(datas[4]);
164             float height = Float.parseFloat(datas[5]);
165
166             float left = centerX - (width / 2.0f);
167             float top = centerY - (height / 2.0f);
168
169             // オブジェクトのデータを作成する
170             MeMoMaObjectHolder.PositionObject pos = objectHolder.createPosition(left, top, drawStyle);
171             if (pos == null)
172             {
173                 Log.v(Main.APP_IDENTIFIER, "parseRecord() : object create failure.");
174                 return;                 
175             }
176             pos.rect.right = left + width;
177             pos.rect.bottom = top + height;
178             pos.label = label;
179             pos.detail = detail;
180             pos.paintStyle = paintStyle;
181             pos.userChecked = userChecked;
182             Log.v(Main.APP_IDENTIFIER, "OBJECT CREATED: " + label + "(" + left + "," + top + ") [" +drawStyle + "]");
183         }
184         catch (Exception ex)
185         {
186                 Log.v(Main.APP_IDENTIFIER, "parseRecord() " + ex.toString());
187         }
188         
189     }
190
191     
192     /**
193      *    (CSV形式の)データを読み込んで格納する。
194      * 
195      * @param fileName
196      * @param objectHolder
197      * @return
198      */
199     private String importFromCsvFile(String fileName, MeMoMaObjectHolder objectHolder)
200     {
201         String resultMessage = "";
202         try
203         {
204             Log.v(Main.APP_IDENTIFIER, "CSV(import)>> " + fileName);                    
205                 BufferedReader buf = new BufferedReader(new FileReader(fileName));
206             String dataLine = readRecord(buf);
207             while (dataLine != null)
208             {
209                         if (dataLine.startsWith(";") != true)
210                         {
211                                 // データ行だった。ログに出力する!
212                     parseRecord(dataLine, objectHolder);
213                         }
214                 // 次のデータ行を読み出す
215                         dataLine = readRecord(buf);
216             }
217         }
218         catch (Exception e)
219         {
220                 resultMessage = " ERR(import)>" + e.toString();
221             Log.v(Main.APP_IDENTIFIER, resultMessage);
222             e.printStackTrace();
223         } 
224         return (resultMessage);
225     }
226
227     /**
228      *  非同期処理
229      *  (バックグラウンドで実行する(このメソッドは、UIスレッドと別のところで実行する))
230      * 
231      */
232     @Override
233     protected String doInBackground(MeMoMaObjectHolder... datas)
234     {           
235         // ファイル名の設定 ... (拡張子なし)
236         String fileName = fileUtility.getGokigenDirectory() + "/exported/" + targetFileName;
237
238         // データを読み込む
239         String result = importFromCsvFile(fileName, datas[0]);
240
241         // データを保存する
242         MeMoMaFileSavingEngine savingEngine = new MeMoMaFileSavingEngine(fileUtility, backgroundUri, userCheckboxString);
243         String message = savingEngine.saveObjects(datas[0]);
244
245         System.gc();
246
247                 return (result + " " + message);
248     }
249
250     /**
251      *  非同期処理の進捗状況の更新
252      * 
253      */
254         @Override
255         protected void onProgressUpdate(Integer... values)
256         {
257         // 今回は何もしない
258         }
259
260     /**
261      *  非同期処理の後処理
262      *  (結果を応答する)
263      */
264     @Override
265     protected void onPostExecute(String result)
266     {
267         try
268         {
269             if (receiver != null)
270             {
271                 receiver.onImportedResult(result + "  " + fileSavedResult);
272             }
273             fileSavedResult = "";
274         }
275         catch (Exception ex)
276         {
277                 Log.v(Main.APP_IDENTIFIER, "MeMoMaFileImportCsvProcess::onPostExecute() : " + ex.toString());
278         }
279         // プログレスダイアログを消す
280         importingDialog.dismiss();
281
282         return;
283     }
284     
285     public void onSavedResult(String detail)
286     {
287         fileSavedResult = detail;
288     }
289
290     public void setSavingStatus(boolean isSaving)
291     {
292         
293     }
294
295     public boolean getSavingStatus()
296     {
297         return (false);
298     }
299
300     /**
301      *    結果報告用のインタフェース(積極的に使う予定はないけど...)
302      *    
303      * @author MRSa
304      *
305      */
306     public interface IResultReceiver
307     {
308         /**  保存結果の報告 **/
309         public abstract void onImportedResult(String detail);
310     }
311 }