3
3
import android .app .AlertDialog ;
4
4
import android .app .Dialog ;
5
5
import android .app .ListActivity ;
6
- import android .content .DialogInterface ;
7
- import android .content .Intent ;
8
- import android .content .SharedPreferences ;
6
+ import android .content .*;
7
+ import android .os .AsyncTask ;
9
8
import android .os .Bundle ;
9
+ import android .os .IBinder ;
10
10
import android .preference .PreferenceManager ;
11
11
import android .util .Log ;
12
12
import android .view .LayoutInflater ;
16
16
import android .widget .EditText ;
17
17
import android .widget .ListView ;
18
18
import android .widget .Toast ;
19
+ import com .thoughtworks .studios .driod .citracker .FeedParser ;
19
20
import com .thoughtworks .studios .driod .citracker .FeedParserFactory ;
20
21
import com .thoughtworks .studios .driod .citracker .MainMenuOptions ;
21
22
import com .thoughtworks .studios .driod .citracker .R ;
23
+ import com .thoughtworks .studios .driod .citracker .model .Message ;
22
24
import com .thoughtworks .studios .driod .citracker .model .Pipeline ;
25
+ import com .thoughtworks .studios .driod .citracker .service .LocalService ;
23
26
import com .thoughtworks .studios .driod .citracker .view .PipelineListAdapter ;
24
27
28
+ import java .util .ArrayList ;
25
29
import java .util .List ;
26
30
27
31
/**
28
32
* Understands named pipeline and show them with the information from the
29
33
* lastest run. Pass/fail
30
34
*/
31
35
public class PipelineList extends ListActivity {
32
- private List <Pipeline > pipelines ;
33
36
public static final String SELECTED_PIPELINE_URL_KEY = "com.thoughtworks.studios.driod.citracker.activity.CurrentPipelineName" ;
37
+ private boolean mIsBound ;
38
+ private PipelineListAdapter pipelineListAdapter ;
34
39
35
40
@ Override
36
41
public void onCreate (Bundle icicle ) {
37
42
super .onCreate (icicle );
38
43
setContentView (R .layout .main );
39
- reload ();
44
+ pipelineListAdapter = new PipelineListAdapter (this , R .layout .row );
45
+ this .setListAdapter (pipelineListAdapter );
46
+ loadPipelines ();
47
+ pipelineListAdapter .notifyDataSetChanged ();
40
48
}
41
49
42
- @ Override
43
- protected void onResume () {
44
- super .onResume ();
45
- reload ();
46
- }
50
+ private void loadPipelines () {
51
+ Context applicationContext = getApplicationContext ();
52
+ List <String > pipelineNames = FeedParserFactory .getPipelineString (applicationContext );
53
+ for (String name : pipelineNames ) {
54
+ new LoadPipelineFeedTask ().execute (name );
55
+ }
47
56
48
- private void reload () {
49
- pipelines = FeedParserFactory .loadPipelines (this );
50
- this .setListAdapter (new PipelineListAdapter (this , R .layout .row , pipelines ));
51
57
}
52
58
53
- @ Override
54
- public void onContentChanged () {
55
- super .onContentChanged ();
56
- reload ();
59
+
60
+ private class LoadPipelineFeedTask extends AsyncTask <String , String , Pipeline > {
61
+ private Pipeline loadSinglePipeline (String pipelineName ) {
62
+ Context applicationContext = PipelineList .this .getApplicationContext ();
63
+ String serverString = FeedParserFactory .getServerString (applicationContext );
64
+ String serverUrl = String .format (serverString + "/go/api/pipelines/%s/stages.xml" , pipelineName );
65
+ String authString = FeedParserFactory .getAuthString (applicationContext );
66
+ publishProgress ("Pipeline List" + "loading feeds" + serverUrl );
67
+ FeedParser parser = FeedParserFactory .getParser (serverUrl , authString );
68
+ long start = System .currentTimeMillis ();
69
+ List <Message > messages = new ArrayList <Message >();
70
+ try {
71
+ messages = parser .parse ();
72
+ } catch (Throwable t ) {
73
+ publishProgress (
74
+ String .format ("Unable to load pipeline %s with auth :%s for url %s" ,
75
+ pipelineName ,
76
+ authString ,
77
+ serverUrl ));
78
+ }
79
+ long duration = System .currentTimeMillis () - start ;
80
+ publishProgress ("Go Feeds" + "Parser duration=" + duration );
81
+ return new Pipeline (messages , pipelineName , serverUrl );
82
+ }
83
+
84
+ @ Override
85
+ protected Pipeline doInBackground (String ... params ) {
86
+ return loadSinglePipeline (params [0 ]);
87
+ }
88
+
89
+ @ Override
90
+ protected void onProgressUpdate (String ... progress ) {
91
+ Toast .makeText (getApplicationContext (), progress [0 ], Toast .LENGTH_SHORT ).show ();
92
+ }
93
+
94
+ @ Override
95
+ protected void onPostExecute (Pipeline pipeline ) {
96
+ pipelineListAdapter .add (pipeline );
97
+ pipelineListAdapter .notifyDataSetChanged ();
98
+ }
57
99
}
58
100
59
101
@ Override
60
102
public boolean onCreateOptionsMenu (Menu menu ) {
61
103
super .onCreateOptionsMenu (menu );
62
104
menu .add (Menu .NONE , MainMenuOptions .ADD_PIPELINE .ordinal (), MainMenuOptions .ADD_PIPELINE .ordinal (), R .string .add_pipeline );
63
105
menu .add (Menu .NONE , MainMenuOptions .PREFERENCES .ordinal (), MainMenuOptions .PREFERENCES .ordinal (), R .string .preferences );
106
+ menu .add (Menu .NONE , MainMenuOptions .ADD_GO_URL .ordinal (), MainMenuOptions .ADD_GO_URL .ordinal (), R .string .add_go_url );
64
107
return true ;
65
108
}
66
109
@@ -75,18 +118,23 @@ protected Dialog onCreateDialog(int id) {
75
118
.setPositiveButton (R .string .ok , new DialogInterface .OnClickListener () {
76
119
public void onClick (DialogInterface dialog , int whichButton ) {
77
120
EditText editView = (EditText ) textEntryView .findViewById (R .id .pipelinename_edit );
78
- String newPipelineName = editView .getText ().toString ().trim ();
79
- SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences (getApplicationContext ());
80
- String existingPipelines = preferences .getString ("pipeline_names" , "" );
81
- SharedPreferences .Editor editor = preferences .edit ();
82
- editor .putString ("pipeline_names" , existingPipelines + "," + newPipelineName );
83
- editor .commit ();
84
- reload ();
121
+ String userInput = editView .getText ().toString ();
122
+ String newPipelineName = userInput .trim ();
123
+ updatePipelinesPreferences (newPipelineName );
85
124
Toast .makeText (PipelineList .this .getApplicationContext (), String .format ("Pipeline %s added." , newPipelineName ), Toast .LENGTH_LONG ).show ();
125
+ new LoadPipelineFeedTask ().execute (newPipelineName );
86
126
}
87
127
}).create ();
88
128
}
89
129
130
+ private void updatePipelinesPreferences (String newPipelineName ) {
131
+ SharedPreferences preferences = PreferenceManager .getDefaultSharedPreferences (getApplicationContext ());
132
+ String existingPipelines = preferences .getString ("pipeline_names" , "" );
133
+ SharedPreferences .Editor editor = preferences .edit ();
134
+ editor .putString ("pipeline_names" , existingPipelines + "," + newPipelineName );
135
+ editor .commit ();
136
+ }
137
+
90
138
@ Override
91
139
public boolean onMenuItemSelected (int featureId , MenuItem item ) {
92
140
super .onMenuItemSelected (featureId , item );
@@ -100,16 +148,78 @@ public boolean onMenuItemSelected(int featureId, MenuItem item) {
100
148
if (option == MainMenuOptions .ADD_PIPELINE ) {
101
149
showDialog (1 );
102
150
}
151
+ if (option == MainMenuOptions .ADD_GO_URL ) {
152
+ createService ();
153
+ }
103
154
return false ;
104
155
}
105
156
157
+ private LocalService mBoundService ;
158
+
159
+ private void createService () {
160
+ doBindService ();
161
+ }
162
+
163
+ private ServiceConnection mConnection = new ServiceConnection () {
164
+ public void onServiceConnected (ComponentName className , IBinder service ) {
165
+ // This is called when the connection with the service has been
166
+ // established, giving us the service object we can use to
167
+ // interact with the service. Because we have bound to a explicit
168
+ // service that we know is running in our own process, we can
169
+ // cast its IBinder to a concrete class and directly access it.
170
+ mBoundService = ((LocalService .LocalBinder ) service ).getService ();
171
+
172
+ // Tell the user about this for our demo.
173
+ Toast .makeText (PipelineList .this , R .string .choose_pipeline ,
174
+ Toast .LENGTH_SHORT ).show ();
175
+ }
176
+
177
+ public void onServiceDisconnected (ComponentName className ) {
178
+ // This is called when the connection with the service has been
179
+ // unexpectedly disconnected -- that is, its process crashed.
180
+ // Because it is running in our same process, we should never
181
+ // see this happen.
182
+ mBoundService = null ;
183
+ Toast .makeText (PipelineList .this , R .string .add_go_url ,
184
+ Toast .LENGTH_SHORT ).show ();
185
+ }
186
+ };
187
+
188
+
106
189
@ Override
107
190
protected void onListItemClick (ListView l , View v , int position , long id ) {
108
191
super .onListItemClick (l , v , position , id );
109
192
Intent myIntent = new Intent ();
110
193
myIntent .setClass (getApplicationContext (), MessageList .class );
111
- myIntent .putExtra (SELECTED_PIPELINE_URL_KEY , pipelines .get (position ).getPipelineFeedUrl ());
194
+ Object itemIdAtPosition = l .getItemAtPosition (position );
195
+ myIntent .putExtra (SELECTED_PIPELINE_URL_KEY , ((Pipeline ) itemIdAtPosition ).getPipelineFeedUrl ());
112
196
startActivity (myIntent );
113
197
}
114
198
199
+
200
+ void doBindService () {
201
+ // Establish a connection with the service. We use an explicit
202
+ // class name because we want a specific service implementation that
203
+ // we know will be running in our own process (and thus won't be
204
+ // supporting component replacement by other applications).
205
+ bindService (new Intent (PipelineList .this ,
206
+ LocalService .class ), mConnection , Context .BIND_AUTO_CREATE );
207
+ mIsBound = true ;
208
+ }
209
+
210
+ void doUnbindService () {
211
+ if (mIsBound ) {
212
+ // Detach our existing connection.
213
+ unbindService (mConnection );
214
+ mIsBound = false ;
215
+ }
216
+ }
217
+
218
+ @ Override
219
+ protected void onDestroy () {
220
+ super .onDestroy ();
221
+ doUnbindService ();
222
+ }
223
+
224
+
115
225
}
0 commit comments