Statistics
| Branch: | Revision:

root / src / com / rackspacecloud / android / ListAccountsActivity.java @ f39579c4

History | View | Annotate | Download (12.3 kB)

1
package com.rackspacecloud.android;
2

    
3
import java.io.FileInputStream;
4
import java.io.FileNotFoundException;
5
import java.io.FileOutputStream;
6
import java.io.IOException;
7
import java.io.ObjectInputStream;
8
import java.io.ObjectOutputStream;
9
import java.io.StreamCorruptedException;
10
import java.util.ArrayList;
11
import java.util.TreeMap;
12

    
13
import com.rackspace.cloud.servers.api.client.Account;
14
import com.rackspace.cloud.servers.api.client.Flavor;
15
import com.rackspace.cloud.servers.api.client.FlavorManager;
16
import com.rackspace.cloud.servers.api.client.Image;
17
import com.rackspace.cloud.servers.api.client.ImageManager;
18
import com.rackspace.cloud.servers.api.client.http.Authentication;
19

    
20
import android.app.AlertDialog;
21
import android.app.ListActivity;
22
import android.app.ProgressDialog;
23
import android.content.Context;
24
import android.content.DialogInterface;
25
import android.content.Intent;
26
import android.os.AsyncTask;
27
import android.os.Bundle;
28
import android.util.Log;
29
import android.view.ContextMenu;
30
import android.view.ContextMenu.ContextMenuInfo;
31
import android.view.LayoutInflater;
32
import android.view.Menu;
33
import android.view.MenuInflater;
34
import android.view.MenuItem;
35
import android.view.View;
36
import android.view.ViewGroup;
37
import android.widget.AdapterView.AdapterContextMenuInfo;
38
import android.widget.ArrayAdapter;
39
import android.widget.ImageView;
40
import android.widget.ListView;
41
import android.widget.TextView;
42

    
43
public class ListAccountsActivity extends ListActivity{
44

    
45
        private ArrayList<Account> accounts;
46
        private final String FILENAME = "accounts.data";
47
        private Intent tabViewIntent;
48
        private boolean authenticating;
49
        private ProgressDialog dialog;
50
        private Context context;
51

    
52
        public void onCreate(Bundle savedInstanceState) {
53
        super.onCreate(savedInstanceState);
54
        onRestoreInstanceState(savedInstanceState);
55
        //restoreState(savedInstanceState);
56
        registerForContextMenu(getListView());
57
        context = getApplicationContext();
58
        tabViewIntent = new Intent(this, TabViewActivity.class);
59
    }
60

    
61
        @Override
62
        protected void onSaveInstanceState(Bundle outState) {
63
                super.onSaveInstanceState(outState);
64
                outState.putBoolean("authenticating", authenticating);
65
                //need to set authenticating back to true because it is set to false
66
                //in hideDialog()
67
                if(authenticating){
68
                        hideDialog();
69
                        authenticating = true;
70
                }
71
                writeAccounts();
72
        }
73
        
74
        @Override
75
        protected void onRestoreInstanceState(Bundle state) {
76
                if (state != null && state.containsKey("authenticating") && state.getBoolean("authenticating")) {
77
                    showDialog();
78
            } else {
79
                    hideDialog();
80
            }
81
                if (state != null && state.containsKey("accounts")) {
82
                    accounts = readAccounts();
83
                    if (accounts.size() == 0) {
84
                            displayNoAccountsCell();
85
                    } else {
86
                            getListView().setDividerHeight(1); // restore divider lines 
87
                            setListAdapter(new AccountAdapter());
88
                    }
89
            } else {
90
            loadAccounts();        
91
            }         
92
    }
93
        
94
        @Override
95
        protected void onStart(){
96
                super.onStart();
97
                if(authenticating){
98
                        showDialog();
99
                }
100
        }
101
        
102
        @Override
103
        protected void onStop(){
104
                super.onStop();
105
                if(authenticating){
106
                        hideDialog();
107
                        authenticating = true;
108
                }
109
        }
110
                
111
        private void loadAccounts() {
112
                //check and see if there are any in memory
113
                if(accounts == null){
114
                        accounts = readAccounts();
115
                }
116
                //if nothing was written before accounts will still be null
117
                if(accounts == null){
118
                        accounts = new ArrayList<Account>();
119
                }
120

    
121
                setAccountList();
122
        }
123

    
124
        private void setAccountList() {
125
        
126
                if (accounts.size() == 0) {
127
                        displayNoAccountsCell();
128
                } else {
129
                        getListView().setDividerHeight(1); // restore divider lines 
130
                        this.setListAdapter(new AccountAdapter());
131
                }
132
        }
133

    
134
        private void writeAccounts(){
135
                FileOutputStream fos;
136
                ObjectOutputStream out = null;
137
                try{
138
                        fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
139
                        out = new ObjectOutputStream(fos);
140
                        out.writeObject(accounts);
141
                        out.flush();
142
                        out.close();
143
                } catch (FileNotFoundException e) {
144
                        showAlert("Error", "Could not save accounts.");
145
                        e.printStackTrace();
146
                } catch (IOException e) {
147
                        showAlert("Error", "Could not save accounts.");
148
                        e.printStackTrace();
149
                }
150
        }
151

    
152
        private ArrayList<Account> readAccounts(){
153
                FileInputStream fis;
154
                ObjectInputStream in;
155
                try {
156
                        fis = openFileInput(FILENAME);
157
                        in = new ObjectInputStream(fis);
158
                        ArrayList<Account> file = (ArrayList<Account>)in.readObject();
159
                        in.close();
160
                        return file;
161
                } catch (FileNotFoundException e) {
162
                        //showAlert("Error", "Could not load accounts.");
163
                        e.printStackTrace();
164
                        return null;
165
                } catch (StreamCorruptedException e) {
166
                        showAlert("Error", "Could not load accounts.");
167
                        e.printStackTrace();
168
                } catch (IOException e) {
169
                        showAlert("Error", "Could not load accounts.");
170
                        e.printStackTrace();
171
                } catch (ClassNotFoundException e) {
172
                        showAlert("Error", "Could not load accounts.");
173
                        e.printStackTrace();
174
                }
175
                return null;
176
                
177
        }
178

    
179
        private void displayNoAccountsCell() {
180
            String a[] = new String[1];
181
            a[0] = "No Accounts";
182
        setListAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.noaccountscell, R.id.no_accounts_label, a));
183
        getListView().setTextFilterEnabled(true);
184
        getListView().setDividerHeight(0); // hide the dividers so it won't look like a list row
185
        getListView().setItemsCanFocus(false);
186
    }
187
        
188
        protected void onListItemClick(ListView l, View v, int position, long id) {
189
                if (accounts != null && accounts.size() > 0) {
190
                        //setActivityIndicatorsVisibility(View.VISIBLE, v);
191
                        Account.setAccount(accounts.get(position));
192
                        login();
193
                }                
194
    }
195
        
196
        public void login() {
197
        //showActivityIndicators();
198
        //setLoginPreferences();
199
        new AuthenticateTask().execute((Void[]) null);
200
    }
201
        
202
        //setup menu for when menu button is pressed
203
        public boolean onCreateOptionsMenu(Menu menu) {
204
                super.onCreateOptionsMenu(menu);
205
                MenuInflater inflater = getMenuInflater();
206
                inflater.inflate(R.menu.accounts_list_menu, menu);
207
                return true;
208
        } 
209
    
210
    @Override 
211
    //in options menu, when add account is selected go to add account activity
212
    public boolean onOptionsItemSelected(MenuItem item) {
213
                switch (item.getItemId()) {
214
                case R.id.add_account:
215
                        startActivityForResult(new Intent(this, AddAccountActivity.class), 78); // arbitrary number; never used again
216
                        return true;
217
                }
218
                return false;
219
        } 
220

    
221
    //the context menu for a long press on an account
222
        public void onCreateContextMenu(ContextMenu menu, View v,
223
                        ContextMenuInfo menuInfo) {
224
                super.onCreateContextMenu(menu, v, menuInfo);
225
                MenuInflater inflater = getMenuInflater();
226
                inflater.inflate(R.menu.account_context_menu, menu);
227
        }
228

    
229
        //removes the selected account from account list if remove is clicked
230
        public boolean onContextItemSelected(MenuItem item) {
231
                AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
232
                accounts.remove(info.position);
233
                writeAccounts();
234
                loadAccounts();
235
                return true;
236
        }
237

    
238
        class AccountAdapter extends ArrayAdapter<Account> {
239

    
240
                AccountAdapter() {
241
                        super(ListAccountsActivity.this, R.layout.listaccountcell, accounts);
242
                }
243
                
244
                public View getView(int position, View convertView, ViewGroup parent) {
245
                        
246
                        LayoutInflater inflater = getLayoutInflater();
247
                        View row = inflater.inflate(R.layout.listaccountcell, parent, false);
248

    
249
                        TextView label = (TextView) row.findViewById(R.id.label);
250
                        label.setText(accounts.get(position).getUsername());
251
                        
252
                        TextView sublabel = (TextView) row.findViewById(R.id.sublabel);
253
                        sublabel.setText(getAccountServer(accounts.get(position)));
254
                        
255
                        ImageView icon = (ImageView) row.findViewById(R.id.account_type_icon);
256
                        icon.setImageResource(setAccountIcon(accounts.get(position)));
257
                        
258
                        return row;
259
                }
260
        }
261
        
262
        public String getAccountServer(Account account){
263
                String authServer = account.getAuthServer();
264
                String result;
265
                if(authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER)){
266
                        result = "Rackspace Cloud (UK)";
267
                }
268
                else if(authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER)){
269
                        result = "Rackspace Cloud (US)";
270
                }
271
                else{
272
                        result = "Custom";
273
                        //setCustomIcon();
274
                }
275
                return result;
276
        }
277
        
278
        //display rackspace logo for cloud accounts and openstack logo for others
279
        private int setAccountIcon(Account account){
280
                if(account.getAuthServer().equals(Preferences.COUNTRY_UK_AUTH_SERVER) 
281
                                || account.getAuthServer().equals(Preferences.COUNTRY_US_AUTH_SERVER)){
282
                        return R.drawable.rackspacecloud_icon;
283
                }
284
                else{
285
                        return R.drawable.openstack_icon;
286
                }
287
        }
288

    
289
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
290
                super.onActivityResult(requestCode, resultCode, data);
291
                
292
                if (resultCode == RESULT_OK && requestCode == 78) {          
293
                        Account acc = new Account();
294
                        Bundle b = data.getBundleExtra("accountInfo");
295
                        acc.setApiKey(b.getString("apiKey"));
296
                        acc.setUsername(b.getString("username"));
297
                        acc.setAuthServer(b.getString("server"));
298
                        accounts.add(acc);
299
                        writeAccounts();
300
                        loadAccounts();
301
                }
302
        }        
303
/*
304
        private void setActivityIndicatorsVisibility(int visibility) {
305
                //FINISH THIS TO LET USER KNOW PROGRAM IS STILL WORKING
306
                
307
        //ProgressBar pb = new ProgressBar();
308
            //TextView tv = (TextView) findViewById(R.id.login_authenticating_label);
309
        //pb.setVisibility(visibility);
310
        //tv.setVisibility(visibility);
311
    }
312
        
313
        private void setActivityIndicatorsVisibility(int visibility, View v) {
314
                //FINISH THIS TO LET USER KNOW PROGRAM IS STILL WORKING
315
                
316
        //ProgressBar pb = new ProgressBar();
317
            //TextView tv = (TextView) findViewById(R.id.login_authenticating_label);
318
        //pb.setVisibility(visibility);
319
        //tv.setVisibility(visibility);
320
    }
321
*/
322
        
323
        private void showDialog() {
324
                authenticating = true;
325
                dialog = ProgressDialog.show(ListAccountsActivity.this, "", "Authenticating...", true);
326
    }
327
    
328
    private void hideDialog() {
329
            if(dialog != null){
330
                    dialog.dismiss();
331
            }
332
            authenticating = false;
333
    }
334

    
335
        private class AuthenticateTask extends AsyncTask<Void, Void, Boolean> {
336
            
337
                @Override
338
                protected void onPreExecute(){
339
                        showDialog();
340
                }
341
                
342
                @Override
343
                protected Boolean doInBackground(Void... arg0) {
344
                        return new Boolean(Authentication.authenticate(context));
345
                        //return true;
346
                }
347
            
348
                @Override
349
                protected void onPostExecute(Boolean result) {
350
                        if (result.booleanValue()) {
351
                                //startActivity(tabViewIntent);
352
                        new LoadImagesTask().execute((Void[]) null);
353
                        } else {
354
                                hideDialog();
355
                                showAlert("Login Failure", "Authentication failed.  Please check your User Name and API Key.");
356
                        }
357
                }
358
    }
359

    
360
    private class LoadFlavorsTask extends AsyncTask<Void, Void, ArrayList<Flavor>> {
361
            
362
                @Override
363
                protected ArrayList<Flavor> doInBackground(Void... arg0) {
364
                        return (new FlavorManager()).createList(true, context);
365
                }
366
            
367
                @Override
368
                protected void onPostExecute(ArrayList<Flavor> result) {
369
                        if (result != null && result.size() > 0) {
370
                                TreeMap<String, Flavor> flavorMap = new TreeMap<String, Flavor>();
371
                                for (int i = 0; i < result.size(); i++) {
372
                                        Flavor flavor = result.get(i);
373
                                        flavorMap.put(flavor.getId(), flavor);
374
                                }
375
                                Flavor.setFlavors(flavorMap);
376
                                hideDialog();
377
                                startActivity(tabViewIntent);
378
                        } else {
379
                                hideDialog();
380
                                showAlert("Login Failure", "There was a problem loading server flavors.  Please try again.");
381
                        }
382
                }
383
    }
384

    
385
    private class LoadImagesTask extends AsyncTask<Void, Void, ArrayList<Image>> {
386
            
387
                @Override
388
                protected ArrayList<Image> doInBackground(Void... arg0) {
389
                        return (new ImageManager()).createList(true, context);
390
                }
391
            
392
                @Override
393
                protected void onPostExecute(ArrayList<Image> result) {
394
                        if (result != null && result.size() > 0) {
395
                                TreeMap<String, Image> imageMap = new TreeMap<String, Image>();
396
                                for (int i = 0; i < result.size(); i++) {
397
                                        Image image = result.get(i);
398
                                        imageMap.put(image.getId(), image);
399
                                }
400
                                Image.setImages(imageMap);
401
                                new LoadFlavorsTask().execute((Void[]) null);
402
                                //startActivity(tabViewIntent);
403
                        } else {
404
                                hideDialog();
405
                                showAlert("Login Failure", "There was a problem loading server images.  Please try again.");
406
                        }
407
                }
408
    }
409
    
410
    private void showAlert(String title, String message) {
411
                AlertDialog alert = new AlertDialog.Builder(this).create();
412
                alert.setTitle(title);
413
                alert.setMessage(message);
414
                alert.setButton("OK", new DialogInterface.OnClickListener() {
415
              public void onClick(DialogInterface dialog, int which) {
416
                return;
417
            } }); 
418
                alert.show();
419
    }
420
        
421
                
422
}