Statistics
| Branch: | Revision:

root / src / com / rackspacecloud / android / ContainerObjectDetails.java @ 639ae8d6

History | View | Annotate | Download (18.7 kB)

1
package com.rackspacecloud.android;
2

    
3
import java.io.BufferedOutputStream;
4
import java.io.File;
5
import java.io.FileNotFoundException;
6
import java.io.FileOutputStream;
7
import java.io.IOException;
8
import java.io.StringReader;
9

    
10
import javax.xml.parsers.FactoryConfigurationError;
11
import javax.xml.parsers.ParserConfigurationException;
12
import javax.xml.parsers.SAXParser;
13
import javax.xml.parsers.SAXParserFactory;
14

    
15
import org.apache.http.HttpEntity;
16
import org.apache.http.HttpResponse;
17
import org.apache.http.client.ClientProtocolException;
18
import org.apache.http.impl.client.BasicResponseHandler;
19
import org.apache.http.util.EntityUtils;
20
import org.xml.sax.InputSource;
21
import org.xml.sax.SAXException;
22
import org.xml.sax.XMLReader;
23

    
24
import android.app.Activity;
25
import android.app.AlertDialog;
26
import android.app.Dialog;
27
import android.app.ProgressDialog;
28
import android.content.Context;
29
import android.content.DialogInterface;
30
import android.content.Intent;
31
import android.net.Uri;
32
import android.os.AsyncTask;
33
import android.os.Bundle;
34
import android.os.Environment;
35
import android.util.Log;
36
import android.view.Menu;
37
import android.view.MenuInflater;
38
import android.view.MenuItem;
39
import android.view.View;
40
import android.widget.Button;
41
import android.widget.TextView;
42
import android.widget.Toast;
43

    
44
import com.rackspace.cloud.files.api.client.ContainerObjectManager;
45
import com.rackspace.cloud.files.api.client.ContainerObjects;
46
import com.rackspace.cloud.servers.api.client.CloudServersException;
47
import com.rackspace.cloud.servers.api.client.http.HttpBundle;
48
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser;
49

    
50
/** 
51
 * 
52
 * @author Phillip Toohill
53
 *
54
 */
55

    
56
public class ContainerObjectDetails extends Activity {
57

    
58
        private static final int deleteObject = 0;
59
        private final String DOWNLOAD_DIRECTORY = "/RackspaceCloud";
60
        private ContainerObjects objects;
61
        private String containerNames;
62
        private String cdnURL;
63
        private String cdnEnabled;
64
        public String LOG = "ViewObject";
65
        private int bConver = 1048576;
66
        private int kbConver = 1024;
67
        private double megaBytes;
68
        private double kiloBytes;
69
        public Button previewButton;
70
        public Button downloadButton;
71
        public Context context;
72
        private boolean displayDialog;
73
        private ProgressDialog dialog;
74
        private Boolean isDownloaded;
75
        private AndroidCloudApplication app;
76
        private DeleteObjectListenerTask deleteObjTask;
77
        private DownloadObjectListenerTask downloadObjTask;
78
        
79
        /** Called when the activity is first created. */
80
        @Override
81
        public void onCreate(Bundle savedInstanceState) {
82
                super.onCreate(savedInstanceState);
83

    
84
                context = getApplicationContext();
85

    
86
                objects = (ContainerObjects) this.getIntent().getExtras().get("container");
87
                containerNames =  (String) this.getIntent().getExtras().get("containerNames");
88
                cdnURL = (String) this.getIntent().getExtras().get("cdnUrl");
89
                cdnEnabled = (String) this.getIntent().getExtras().get("isCdnEnabled");
90

    
91

    
92
                setContentView(R.layout.viewobject);       
93
                restoreState(savedInstanceState);
94

    
95
        }
96

    
97
        @Override
98
        protected void onSaveInstanceState(Bundle outState) {
99
                super.onSaveInstanceState(outState);
100
                outState.putSerializable("container", objects);
101
                outState.putBoolean("isDownloaded", isDownloaded);
102
                outState.putBoolean("displayDialog", displayDialog);
103
                
104
                if(displayDialog){
105
                        hideDialog();
106
                        displayDialog = true;
107
                }
108
        }
109

    
110
        private void restoreState(Bundle state) {
111
                
112
                /*
113
                 * need reference to the app so you can access curDirFiles
114
                 * as well as processing status
115
                 */
116
                app = (AndroidCloudApplication)this.getApplication();
117

    
118
                if (state != null && state.containsKey("displayDialog") && state.getBoolean("displayDialog")) {
119
                    showDialog();
120
            } else {
121
                    hideDialog();
122
            }
123
                
124
                if (state != null && state.containsKey("container")) {
125
                        objects = (ContainerObjects) state.getSerializable("container");
126
                }
127
                loadObjectData();
128

    
129
                if ( cdnEnabled.equals("true"))  {
130
                        this.previewButton = (Button) findViewById(R.id.preview_button);
131
                        previewButton.setOnClickListener(new MyOnClickListener());
132
                } else {
133
                        this.previewButton = (Button) findViewById(R.id.preview_button);
134
                        previewButton.setVisibility(View.GONE);
135
                }
136

    
137
                if (state != null && state.containsKey("isDownloaded")){
138
                        isDownloaded = state.getBoolean("isDownloaded");
139
                }
140
                else{
141
                        isDownloaded = fileIsDownloaded();
142
                }
143
                this.downloadButton = (Button) findViewById(R.id.download_button);
144
                if ( isDownloaded )  {
145
                        downloadButton.setText("Open File");
146
                } else {
147
                        downloadButton.setText("Download File");
148
                }           
149
                downloadButton.setOnClickListener(new MyOnClickListener());
150
                
151
                if(app.isDeletingObject()){
152
                        deleteObjTask = new DeleteObjectListenerTask();
153
                        deleteObjTask.execute();
154
                }
155
                
156
                if(app.isDownloadingObject()){
157
                        downloadObjTask = new DownloadObjectListenerTask();
158
                        downloadObjTask.execute();
159
                }
160
        }
161
        
162
        
163
        @Override
164
        protected void onStart(){
165
                super.onStart();
166
                if(displayDialog){
167
                        showDialog();
168
                }
169
        }
170

    
171
        
172
        @Override
173
        protected void onStop(){
174
                super.onStop();
175

    
176
                if(displayDialog){
177
                        hideDialog();
178
                        displayDialog = true;
179
                }
180

    
181
                /*
182
                 * Need to stop running listener task
183
                 * if we exit
184
                 */
185
                if(deleteObjTask != null){
186
                        deleteObjTask.cancel(true);
187
                }
188
                
189
                if(downloadObjTask != null){
190
                        downloadObjTask.cancel(true);
191
                }
192
        }
193

    
194

    
195
        private void loadObjectData() {
196
                //Object Name
197
                TextView name = (TextView) findViewById(R.id.view_container_name);
198
                name.setText(objects.getCName().toString());
199

    
200
                //File size
201
                if (objects.getBytes() >= bConver) {
202
                        megaBytes = Math.abs(objects.getBytes()/bConver + 0.2);
203
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
204
                        sublabel.setText(megaBytes + " MB");
205
                } else if (objects.getBytes() >= kbConver){
206
                        kiloBytes = Math.abs(objects.getBytes()/kbConver + 0.2);
207
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
208
                        sublabel.setText(kiloBytes + " KB");
209
                } else {
210
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
211
                        sublabel.setText(objects.getBytes() + " B");
212
                }        
213

    
214
                //Content Type
215
                TextView cType = (TextView) findViewById(R.id.view_content_type);
216
                cType.setText(objects.getContentType().toString());
217

    
218
                //Last Modification date
219
                String strDate = objects.getLastMod();
220
                strDate = strDate.substring(0, strDate.indexOf('T'));
221
                /*
222
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.ssssss");
223
                Date dateStr = null;
224
                try {
225
                        dateStr = formatter.parse(strDate);
226
                } catch (ParseException e1) {
227
                        e1.printStackTrace();
228
                }
229
                String formattedDate = formatter.format(dateStr);
230

231
                Date date1 = null;
232
                try {
233
                        date1 = formatter.parse(formattedDate);
234
                } catch (ParseException e) {
235
                        e.printStackTrace();
236
                }      
237
                formatter = new SimpleDateFormat("MMM-dd-yyyy");
238
                formattedDate = formatter.format(date1);
239
                */
240
                TextView lastmod = (TextView) findViewById(R.id.view_file_modification);
241
                lastmod.setText(strDate);              
242

    
243
        }
244

    
245
        private class MyOnClickListener implements View.OnClickListener {
246
                @Override
247
                public void onClick(View v) {
248
                        if(v.equals(findViewById(R.id.preview_button))){
249
                                Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(cdnURL + "/" + objects.getCName()));
250
                                startActivity(viewIntent);  
251
                        }
252
                        /*
253
                         * need to perform different functions based on if
254
                         * the file is in the devices filesystem
255
                         */
256
                        if(v.equals(findViewById(R.id.download_button))){
257
                                if(!isDownloaded){
258
                                        if(storageIsReady()){
259
                                                new ContainerObjectDownloadTask().execute();
260
                                        }
261
                                        else{
262
                                                showAlert("Error", "Storage not found.");
263
                                        }
264
                                }
265
                                else{
266
                                        openFile();
267
                                }
268
                        }
269
                }
270
        }
271

    
272
        private void showAlert(String title, String message) {
273
                AlertDialog alert = new AlertDialog.Builder(this).create();
274
                alert.setTitle(title);
275
                alert.setMessage(message);
276
                alert.setButton("OK", new DialogInterface.OnClickListener() {
277
                        public void onClick(DialogInterface dialog, int which) {
278
                                return;
279
                        } }); 
280
                alert.show();
281
        }
282
        //Create the Menu options
283
        @Override 
284
        public boolean onCreateOptionsMenu(Menu menu) {
285
                super.onCreateOptionsMenu(menu);
286
                MenuInflater inflater = getMenuInflater();
287
                inflater.inflate(R.menu.container_object_list_menu, menu);
288
                return true;
289
        } 
290

    
291
        @Override 
292
        public boolean onOptionsItemSelected(MenuItem item) {
293
                switch (item.getItemId()) {
294
                case R.id.delete_object:
295
                        showDialog(deleteObject); 
296
                        return true;
297
                case R.id.refresh:
298
                        loadObjectData();
299
                        return true;
300
                }
301
                return false;
302
        } 
303

    
304
        @Override
305
        protected Dialog onCreateDialog(int id ) {
306
                switch (id) {
307
                case deleteObject:
308
                        return new AlertDialog.Builder(ContainerObjectDetails.this)
309
                        .setIcon(R.drawable.alert_dialog_icon)
310
                        .setTitle("Delete File")
311
                        .setMessage("Are you sure you want to delete this file?")
312
                        .setPositiveButton("Delete File", new DialogInterface.OnClickListener() {
313
                                public void onClick(DialogInterface dialog, int whichButton) {
314
                                        // User clicked OK so do some stuff
315
                                        new ContainerObjectDeleteTask().execute((Void[]) null);
316
                                }
317
                        })
318
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
319
                                public void onClick(DialogInterface dialog, int whichButton) {
320
                                        // User clicked Cancel so do some stuff
321
                                }
322
                        })
323
                        .create();
324
                }
325
                return null;
326
        }
327
        /**
328
         * @return the file
329
         */
330
        public ContainerObjects getViewFile() {
331
                return objects;
332
        }
333

    
334
        /**
335
         * @param File the file to set
336
         */
337
        public void setViewFile(ContainerObjects object) {
338
                this.objects = object;
339
        }
340

    
341
        /*
342
         * returns false if external storage is not avaliable
343
         * (if its mounted, missing, read-only, etc)
344
         * from: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
345
         */
346
        private boolean storageIsReady(){
347
                boolean mExternalStorageAvailable = false;
348
                boolean mExternalStorageWriteable = false;
349
                String state = Environment.getExternalStorageState();
350

    
351
                if (Environment.MEDIA_MOUNTED.equals(state)) {
352
                        // We can read and write the media
353
                        mExternalStorageAvailable = mExternalStorageWriteable = true;
354
                } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
355
                        // We can only read the media
356
                        mExternalStorageAvailable = true;
357
                        mExternalStorageWriteable = false;
358
                } else {
359
                        // Something else is wrong. It may be one of many other states, but all we need
360
                        //  to know is we can neither read nor write
361
                        mExternalStorageAvailable = mExternalStorageWriteable = false;
362
                }
363
                return mExternalStorageAvailable && mExternalStorageWriteable;
364
        }
365

    
366
        private boolean fileIsDownloaded(){
367
                if(storageIsReady()){
368
                        String fileName = Environment.getExternalStorageDirectory().getPath() + "/RackspaceCloud/" + objects.getCName();
369
                        File f = new File(fileName);
370
                        return f.isFile();
371
                }
372
                return false;
373
        }
374

    
375
        private void openFile(){
376
                File object = new File(Environment.getExternalStorageDirectory().getPath() + "/RackspaceCloud/" + objects.getCName());
377
                Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
378
                File file = new File(object.getAbsolutePath()); 
379
                String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
380
                String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
381
                myIntent.setDataAndType(Uri.fromFile(file),mimetype);
382
                //myIntent.setData(Uri.fromFile(file));
383
                try{
384
                        startActivity(myIntent);
385
                }
386
                catch(Exception e){
387
                        Toast.makeText(this, "Could not open file.", Toast.LENGTH_SHORT).show();
388
                }
389
        }
390

    
391
        private boolean writeFile(byte[] data){
392
                String directoryName = Environment.getExternalStorageDirectory().getPath() + DOWNLOAD_DIRECTORY;
393
                File f = new File(directoryName);
394

    
395
                if(!f.isDirectory()){
396
                        if(!f.mkdir()){
397
                                return false;
398
                        }
399
                }
400

    
401
                String filename = directoryName + "/" + objects.getCName();
402
                File object = new File(filename);
403
                BufferedOutputStream bos = null;
404

    
405
                try{
406
                        FileOutputStream fos = new FileOutputStream(object);
407
                        bos = new BufferedOutputStream(fos);
408
                        bos.write(data);
409
                }
410
                catch(FileNotFoundException e){
411
                        e.printStackTrace();
412
                }
413
                catch(IOException e){
414
                        e.printStackTrace();
415
                }
416
                finally{
417
                        if(bos != null){
418
                                try {
419
                                        bos.flush();
420
                                        bos.close();
421
                                } catch (IOException e) {
422
                                        // TODO Auto-generated catch block
423
                                        e.printStackTrace();
424
                                }
425
                        }
426
                }
427
                return true;
428
        }
429

    
430
        //Task's
431

    
432
        private CloudServersException parseCloudServersException(HttpResponse response) {
433
                CloudServersException cse = new CloudServersException();
434
                try {
435
                        BasicResponseHandler responseHandler = new BasicResponseHandler();
436
                        String body = responseHandler.handleResponse(response);
437
                        CloudServersFaultXMLParser parser = new CloudServersFaultXMLParser();
438
                        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
439
                        XMLReader xmlReader = saxParser.getXMLReader();
440
                        xmlReader.setContentHandler(parser);
441
                        xmlReader.parse(new InputSource(new StringReader(body)));                            
442
                        cse = parser.getException();                            
443
                } catch (ClientProtocolException e) {
444
                        cse = new CloudServersException();
445
                        cse.setMessage(e.getLocalizedMessage());
446
                } catch (IOException e) {
447
                        cse = new CloudServersException();
448
                        cse.setMessage(e.getLocalizedMessage());
449
                } catch (ParserConfigurationException e) {
450
                        cse = new CloudServersException();
451
                        cse.setMessage(e.getLocalizedMessage());
452
                } catch (SAXException e) {
453
                        cse = new CloudServersException();
454
                        cse.setMessage(e.getLocalizedMessage());
455
                } catch (FactoryConfigurationError e) {
456
                        cse = new CloudServersException();
457
                        cse.setMessage(e.getLocalizedMessage());
458
                }
459
                return cse;
460
        }
461

    
462
        private void startFileError(String message, HttpBundle bundle){
463
                Intent viewIntent = new Intent(getApplicationContext(), ServerErrorActivity.class);
464
                viewIntent.putExtra("errorMessage", message);
465
                viewIntent.putExtra("response", bundle.getResponseText());
466
                viewIntent.putExtra("request", bundle.getCurlRequest());
467
                startActivity(viewIntent);
468
        }
469
        
470
        private void showDialog() {
471
                if(dialog == null || !dialog.isShowing()){
472
                        displayDialog = true;
473
                        dialog = ProgressDialog.show(ContainerObjectDetails.this, "", "Loading...", true);
474
                }
475
    }
476
    
477
    private void hideDialog() {
478
            if(dialog != null){
479
                    dialog.dismiss();
480
            }
481
            displayDialog = false;
482
    }
483

    
484
        private class ContainerObjectDeleteTask extends AsyncTask<Void, Void, HttpBundle> {
485

    
486
                private CloudServersException exception;
487

    
488
                protected void onPreExecute(){
489
                        //dialog = ProgressDialog.show(ContainerObjectDetails.this, "", "Deleting...", true);
490
                        showDialog();
491
                        app.setDeleteingObject(true);
492
                        deleteObjTask = new DeleteObjectListenerTask();
493
                        deleteObjTask.execute();
494
                }
495

    
496
                @Override
497
                protected HttpBundle doInBackground(Void... arg0) {
498
                        HttpBundle bundle = null;        
499
                        try {
500
                                bundle = (new ContainerObjectManager(context)).deleteObject(containerNames, objects.getCName() );
501
                        } catch (CloudServersException e) {
502
                                exception = e;
503
                        }
504
                        
505
                        return bundle;
506
                }
507

    
508
                @Override
509
                protected void onPostExecute(HttpBundle bundle) {
510
                        //dialog.dismiss();
511
                        app.setDeleteingObject(false);
512
                        hideDialog();
513
                        HttpResponse response = bundle.getResponse();
514
                        if (response != null) {
515
                                int statusCode = response.getStatusLine().getStatusCode();
516
                                if (statusCode == 204) {
517
                                        //handled by listner
518
                                } else {
519
                                        CloudServersException cse = parseCloudServersException(response);
520
                                        if ("".equals(cse.getMessage())) {
521
                                                startFileError("There was a problem deleting your File.", bundle);
522
                                        } else {
523
                                                startFileError("There was a problem deleting your file: " + cse.getMessage(), bundle);
524
                                        }
525
                                }
526
                        } else if (exception != null) {
527
                                startFileError("There was a problem deleting your file: " + exception.getMessage(), bundle);                                
528
                        }                        
529
                }
530
        }
531

    
532
        private class ContainerObjectDownloadTask extends AsyncTask<Void, Void, HttpBundle> {
533

    
534
                private CloudServersException exception;
535

    
536
                @Override
537
                protected void onPreExecute(){
538
                        showDialog();
539
                        app.setDownloadingObject(true);
540
                        downloadObjTask = new DownloadObjectListenerTask();
541
                        downloadObjTask.execute();
542
                }
543

    
544
                @Override
545
                protected HttpBundle doInBackground(Void... arg0) {
546
                        HttpBundle bundle = null;        
547
                        try {
548
                                bundle = (new ContainerObjectManager(context)).getObject(containerNames, objects.getCName());
549
                        } catch (CloudServersException e) {
550
                                exception = e;
551
                        }
552
                        return bundle;
553
                }
554

    
555
                @Override
556
                protected void onPostExecute(HttpBundle bundle) {
557
                        app.setDownloadingObject(false);
558
                        hideDialog();
559
                        HttpResponse response = bundle.getResponse();
560
                        if (response != null) {
561
                                int statusCode = response.getStatusLine().getStatusCode();
562
                                if (statusCode == 200) {
563
                                        setResult(Activity.RESULT_OK);
564
                                        HttpEntity entity = response.getEntity();
565
                                        app.setDownloadedEntity(entity);
566
                                        /*
567
                                        try {
568
                                                if(writeFile(EntityUtils.toByteArray(entity))){
569
                                                        downloadButton.setText("Open File");
570
                                                        isDownloaded = true;
571
                                                }
572
                                                else{
573
                                                        showAlert("Error", "There was a problem downloading your file.");
574
                                                }
575

576
                                        } catch (IOException e) {
577
                                                showAlert("Error", "There was a problem downloading your file.");
578
                                                e.printStackTrace();
579
                                        }
580
                                        */
581

    
582
                                } else {
583
                                        CloudServersException cse = parseCloudServersException(response);
584
                                        if ("".equals(cse.getMessage())) {
585
                                                startFileError("There was a problem downloading your File.", bundle);
586
                                        } else {
587
                                                startFileError("There was a problem downloading your file: " + cse.getMessage(), bundle);
588
                                        }
589
                                }
590
                        } else if (exception != null) {
591
                                startFileError("There was a problem downloading your file: " + exception.getMessage(), bundle);                                
592
                        }                        
593
                }
594
        }
595
        
596
        private class DeleteObjectListenerTask extends
597
        AsyncTask<Void, Void, Void> {
598
                
599
                @Override
600
                protected Void doInBackground(Void... arg1) {
601

    
602
                        while(app.isDeletingObject()){
603
                                // wait for process to finish
604
                                // or have it be canceled
605
                                if(deleteObjTask.isCancelled()){
606
                                        return null;
607
                                }
608
                        }
609
                        return null;
610
                }
611

    
612
                /*
613
                 * when no longer processing, time to load
614
                 * the new files
615
                 */
616
                @Override
617
                protected void onPostExecute(Void arg1) {
618
                        hideDialog();
619
                        setResult(99);
620
                        finish();
621
                }
622
        }
623
        
624
        private class DownloadObjectListenerTask extends
625
        AsyncTask<Void, Void, Void> {
626
                
627
                @Override
628
                protected Void doInBackground(Void... arg1) {
629

    
630
                        while(app.isDownloadingObject()){
631
                                // wait for process to finish
632
                                // or have it be canceled
633
                                if(downloadObjTask.isCancelled()){
634
                                        return null;
635
                                }
636
                        }
637
                        return null;
638
                }
639

    
640
                /*
641
                 * when no longer processing, time to load
642
                 * the new files
643
                 */
644
                @Override
645
                protected void onPostExecute(Void arg1) {
646
                        hideDialog();
647
                        try {
648
                                Log.d("info", "captin starting to write");
649
                                if(writeFile(EntityUtils.toByteArray(app.getDownloadedEntity()))){
650
                                        downloadButton.setText("Open File");
651
                                        isDownloaded = true;
652
                                        Log.d("info", "captin wrote");
653
                                }
654
                                else{
655
                                        showAlert("Error", "There was a problem downloading your file.");
656
                                }
657

    
658
                        } catch (IOException e) {
659
                                showAlert("Error", "There was a problem downloading your file.");
660
                                e.printStackTrace();
661
                        } catch (Exception e) {
662
                                showAlert("Error", "There was a problem downloading your file.");
663
                                e.printStackTrace();
664
                        }
665
                }
666
        }
667

    
668
}