Statistics
| Branch: | Revision:

root / src / com / rackspacecloud / android / ContainerObjectDetails.java @ 3e180b04

History | View | Annotate | Download (18.6 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
import java.text.ParseException;
10
import java.text.SimpleDateFormat;
11
import java.util.Date;
12

    
13
import javax.xml.parsers.FactoryConfigurationError;
14
import javax.xml.parsers.ParserConfigurationException;
15
import javax.xml.parsers.SAXParser;
16
import javax.xml.parsers.SAXParserFactory;
17

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

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

    
47
import com.rackspace.cloud.files.api.client.ContainerObjectManager;
48
import com.rackspace.cloud.files.api.client.ContainerObjects;
49
import com.rackspace.cloud.servers.api.client.CloudServersException;
50
import com.rackspace.cloud.servers.api.client.http.HttpBundle;
51
import com.rackspace.cloud.servers.api.client.parsers.CloudServersFaultXMLParser;
52

    
53
/** 
54
 * 
55
 * @author Phillip Toohill
56
 *
57
 */
58

    
59
public class ContainerObjectDetails extends Activity {
60

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

    
87
                context = getApplicationContext();
88

    
89
                objects = (ContainerObjects) this.getIntent().getExtras().get("container");
90
                containerNames =  (String) this.getIntent().getExtras().get("containerNames");
91
                cdnURL = (String) this.getIntent().getExtras().get("cdnUrl");
92
                cdnEnabled = (String) this.getIntent().getExtras().get("isCdnEnabled");
93

    
94

    
95
                setContentView(R.layout.viewobject);       
96
                restoreState(savedInstanceState);
97

    
98
        }
99

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

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

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

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

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

    
174
        
175
        @Override
176
        protected void onStop(){
177
                super.onStop();
178

    
179
                if(displayDialog){
180
                        hideDialog();
181
                        displayDialog = true;
182
                }
183

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

    
197

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

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

    
217
                //Content Type
218
                TextView cType = (TextView) findViewById(R.id.view_content_type);
219
                cType.setText(objects.getContentType().toString());
220

    
221
                //Last Modification date
222
                String strDate = objects.getLastMod();
223
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.ssssss");
224
                Date dateStr = null;
225
                try {
226
                        dateStr = formatter.parse(strDate);
227
                } catch (ParseException e1) {
228
                        e1.printStackTrace();
229
                }
230
                String formattedDate = formatter.format(dateStr);
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
                TextView lastmod = (TextView) findViewById(R.id.view_file_modification);
240
                lastmod.setText(formattedDate);              
241

    
242
        }
243

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

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

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

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

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

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

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

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

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

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

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

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

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

    
429
        //Task's
430

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

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

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

    
485
                private CloudServersException exception;
486

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

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

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

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

    
533
                private CloudServersException exception;
534

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

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

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

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

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

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

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

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

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

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

    
664
}