Refactor the Query & Download thread and progress management out of TCQueryActivity...
[debian/openrocket] / android / src / net / sf / openrocket / android / thrustcurve / TCQueryAction.java
1 package net.sf.openrocket.android.thrustcurve;\r
2 \r
3 import net.sf.openrocket.android.db.DbAdapter;\r
4 import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;\r
5 import android.app.Activity;\r
6 import android.app.AlertDialog;\r
7 import android.app.ProgressDialog;\r
8 import android.content.DialogInterface;\r
9 import android.os.Handler;\r
10 import android.util.Log;\r
11 \r
12 /**\r
13  * TCQueryAction is a class which provides all the functionality required\r
14  * to download motor data from thrustcurve.  It includes UI element for\r
15  * progress and error reporting dialogs.\r
16  * \r
17  * To use the class, instantiate a new instance of TCQueryAction passing in the\r
18  * owning Activity.\r
19  * \r
20  * The Activity should implement TCQueryAction.OnComplete or provide an implementation of\r
21  * TCQueryAction.OnComplete to be notified when the download process is complete.\r
22  * \r
23  * A search and download is started with TCQueryActivity.start( SearchRequest ).  The TCQueryActivity\r
24  * produces and updates a progress dialog.  When the process is complete, the TCQueryActivity will notify\r
25  * the registered TCQueryAction.OnComplete handler.\r
26  * \r
27  * When the parent Activity is dismissed, it must call TCQueryAction.dismiss() to free resources.\r
28  * \r
29  */\r
30 public class TCQueryAction {\r
31 \r
32         public interface OnComplete {\r
33                 public void onComplete();\r
34         }\r
35 \r
36         private final static String TAG = "TCQueryAction";\r
37 \r
38         private DbAdapter mDbHelper;\r
39 \r
40         private ProgressDialog progress;\r
41         private Thread downloadThread;\r
42         private Handler handler;\r
43 \r
44         private final Activity parent;\r
45         private OnComplete onCompleteListener;\r
46 \r
47         /**\r
48          * Create a new TCQueryAction.\r
49          * \r
50          * If the parent implements TCQueryAction.OnComplete, it will be used as the\r
51          * onCompleteListener and notified when the process is finished.\r
52          * \r
53          * @param parent\r
54          */\r
55         public TCQueryAction( Activity parent ) {\r
56                 this.parent = parent;\r
57 \r
58                 mDbHelper = new DbAdapter(this.parent);\r
59                 mDbHelper.open();\r
60 \r
61                 if (parent instanceof OnComplete ) {\r
62                         this.onCompleteListener = (OnComplete) parent;\r
63                 }\r
64         }\r
65 \r
66         public void setOnCompleteListener(OnComplete onCompleteListener) {\r
67                 this.onCompleteListener = onCompleteListener;\r
68         }\r
69         \r
70         public void start( SearchRequest request) {\r
71                 Downloader d = new Downloader(request);\r
72 \r
73                 handler = new Handler();\r
74                 progress = ProgressDialog.show(parent, null, "");\r
75 \r
76                 downloadThread = new Thread( d );\r
77                 downloadThread.start();\r
78 \r
79         }\r
80 \r
81         public void dismiss() {\r
82                 // TODO - need to kill the thread.\r
83                 \r
84                 mDbHelper.close();\r
85                 \r
86                 if ( progress.isShowing() ) {\r
87                         progress.dismiss();\r
88                 }\r
89         }\r
90         \r
91         private class UpdateMessage implements Runnable {\r
92                 private String newMessage;\r
93                 UpdateMessage( String message ) {\r
94                         this.newMessage = message;\r
95                 }\r
96                 @Override\r
97                 public void run() {\r
98                         progress.setMessage(newMessage);\r
99                 }\r
100         }\r
101 \r
102         private class Dismiss implements Runnable {\r
103                 @Override\r
104                 public void run() {\r
105                         progress.dismiss();\r
106                         if (onCompleteListener != null ) {\r
107                                 onCompleteListener.onComplete();\r
108                         }\r
109                         //                      TCQueryActivity.this.finish();\r
110                 }\r
111         }\r
112 \r
113         private class Error implements Runnable {\r
114                 private String newMessage;\r
115                 Error( String message ) {\r
116                         this.newMessage = message;\r
117                 }\r
118                 @Override\r
119                 public void run() {\r
120                         progress.dismiss();\r
121                         final AlertDialog dialog = new AlertDialog.Builder(parent).create();\r
122                         dialog.setMessage(newMessage);\r
123                         dialog.setButton(DialogInterface.BUTTON_NEUTRAL,"Dismiss", new DialogInterface.OnClickListener() {\r
124 \r
125                                 @Override\r
126                                 public void onClick(DialogInterface arg0, int arg1) {\r
127                                         dialog.dismiss();\r
128                                 }\r
129 \r
130                         });\r
131                         dialog.show();\r
132                 }\r
133         }\r
134 \r
135         private class Downloader implements Runnable {\r
136 \r
137                 SearchRequest request;\r
138 \r
139                 Downloader( SearchRequest request ) {\r
140                         this.request = request;\r
141                 }\r
142 \r
143                 @Override\r
144                 public void run() {\r
145                         try {\r
146                                 handler.post( new UpdateMessage("Quering Thrustcurve"));\r
147                                 SearchResponse res = new ThrustCurveAPI().doSearch(request);\r
148 \r
149                                 int total = res.getResults().size();\r
150                                 int count = 1;\r
151                                 for( TCMotor mi : res.getResults() ) {\r
152                                         handler.post(new UpdateMessage("Downloading details " + count + " of " + total));\r
153                                         count++;\r
154                                         if ( mi.getData_files() == null || mi.getData_files().intValue() == 0 ) {\r
155                                                 continue;\r
156                                         }\r
157 \r
158                                         MotorBurnFile b = new ThrustCurveAPI().downloadData(mi.getMotor_id());\r
159 \r
160                                         Log.d(TAG, mi.toString());\r
161 \r
162                                         ExtendedThrustCurveMotor m = new ExtendedThrustCurveMotor();\r
163 \r
164                                         m.setThrustCurveMotor( b.getThrustCurveMotor() );\r
165 \r
166                                         // Convert impulse class.  ThrustCurve puts mmx, 1/4a and 1/2a as A.\r
167                                         m.setImpulseClass(mi.getImpulse_class());\r
168                                         if ( "a".equalsIgnoreCase(mi.getImpulse_class())) {\r
169                                                 if( mi.getCommon_name().startsWith("1/2A") ) {\r
170                                                         m.setImpulseClass("1/2A");\r
171                                                 } else if (mi.getCommon_name().startsWith("1/4A") ) {\r
172                                                         m.setImpulseClass("1/4A");\r
173                                                 } else if (mi.getCommon_name().startsWith("Micro") ) {\r
174                                                         m.setImpulseClass("1/8A");\r
175                                                 }\r
176                                         }\r
177 \r
178                                         // Convert Case Info.\r
179                                         if ( mi.getCase_info() == null\r
180                                                         || "single use".equalsIgnoreCase(mi.getCase_info())\r
181                                                         || "single-use".equalsIgnoreCase(mi.getCase_info())) {\r
182                                                 m.setCaseInfo(mi.getType()+ " " + mi.getDiameter() + "x" + mi.getLength());\r
183                                         } else {\r
184                                                 m.setCaseInfo(mi.getCase_info());\r
185                                         }\r
186 \r
187                                         Log.d(TAG,"adding motor " + m.toString());\r
188                                         // Write motor.\r
189                                         mDbHelper.getMotorDao().insertOrUpdateMotor(m);\r
190                                 }\r
191                                 if ( total < res.getMatches() ) {\r
192                                         handler.post( new Error( total + " motors downloaded, " + res.getMatches() + " matched.  Try restricting the query more.") );\r
193                                 } else {\r
194                                         handler.post( new Dismiss());\r
195                                 }\r
196                         }\r
197                         catch( Exception ex){\r
198                                 Log.d(TAG,ex.toString());\r
199                                 handler.post( new Error(ex.toString()) );\r
200                         }\r
201 \r
202                 }\r
203         }\r
204 \r
205 }\r