Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / ContainerObjectDetails.java @ c99967ba

History | View | Annotate | Download (15.6 kB)

1
package com.rackspace.cloud.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.util.Iterator;
9
import java.util.Map.Entry;
10

    
11
import org.apache.http.HttpEntity;
12
import org.apache.http.HttpResponse;
13
import org.apache.http.util.EntityUtils;
14

    
15
import android.app.Activity;
16
import android.app.AlertDialog;
17
import android.app.Dialog;
18
import android.content.DialogInterface;
19
import android.content.Intent;
20
import android.net.Uri;
21
import android.os.AsyncTask;
22
import android.os.Bundle;
23
import android.os.Environment;
24
import android.util.Log;
25
import android.view.LayoutInflater;
26
import android.view.Menu;
27
import android.view.MenuInflater;
28
import android.view.MenuItem;
29
import android.view.View;
30
import android.widget.Button;
31
import android.widget.LinearLayout;
32
import android.widget.TextView;
33
import android.widget.Toast;
34

    
35
import com.rackspace.cloud.files.api.client.ContainerObjectManager;
36
import com.rackspace.cloud.files.api.client.ContainerObjects;
37
import com.rackspace.cloud.servers.api.client.CloudServersException;
38
import com.rackspace.cloud.servers.api.client.http.HttpBundle;
39

    
40
/** 
41
 * 
42
 * @author Phillip Toohill
43
 *
44
 */
45

    
46
public class ContainerObjectDetails extends CloudActivity {
47

    
48
        private static final int deleteObject = 0;
49
        private final String DOWNLOAD_DIRECTORY = "/RackspaceCloud";
50
        
51
        private ContainerObjects objects;
52
        private String containerNames;
53
        private String cdnURL;
54
        private String cdnEnabled;
55
        public String LOG = "ViewObject";
56
        private int bConver = 1048576;
57
        private int kbConver = 1024;
58
        private double megaBytes;
59
        private double kiloBytes;
60
        public Button previewButton;
61
        public Button downloadButton;
62
        private Boolean isDownloaded;
63
        private AndroidCloudApplication app;
64
        private DeleteObjectListenerTask deleteObjTask;
65
        private DownloadObjectListenerTask downloadObjTask;
66
                
67
        /** Called when the activity is first created. */
68
        @Override
69
        public void onCreate(Bundle savedInstanceState) {
70
                super.onCreate(savedInstanceState);
71
                trackPageView(GoogleAnalytics.PAGE_STORAGE_OBJECT);
72

    
73
                objects = (ContainerObjects) this.getIntent().getExtras().get("container");
74
                containerNames =  (String) this.getIntent().getExtras().get("containerNames");
75
                cdnURL = (String) this.getIntent().getExtras().get("cdnUrl");
76
                cdnEnabled = (String) this.getIntent().getExtras().get("isCdnEnabled");
77

    
78
                setContentView(R.layout.viewobject);       
79
                restoreState(savedInstanceState);
80
        }
81

    
82
        @Override
83
        protected void onSaveInstanceState(Bundle outState) {
84
                super.onSaveInstanceState(outState);
85
                outState.putSerializable("container", objects);
86
                outState.putBoolean("isDownloaded", isDownloaded);
87
        }
88

    
89
        protected void restoreState(Bundle state) {
90
                super.restoreState(state);
91
                /*
92
                 * need reference to the app so you can access curDirFiles
93
                 * as well as processing status
94
                 */
95
                app = (AndroidCloudApplication)this.getApplication();
96

    
97
                if (state != null && state.containsKey("container")) {
98
                        objects = (ContainerObjects) state.getSerializable("container");
99
                }
100
                loadObjectData();
101

    
102
                if ( cdnEnabled.equals("true"))  {
103
                        this.previewButton = (Button) findViewById(R.id.preview_button);
104
                        previewButton.setOnClickListener(new MyOnClickListener());
105
                } else {
106
                        this.previewButton = (Button) findViewById(R.id.preview_button);
107
                        previewButton.setVisibility(View.GONE);
108
                }
109

    
110
                if (state != null && state.containsKey("isDownloaded")){
111
                        isDownloaded = state.getBoolean("isDownloaded");
112
                }
113
                else{
114
                        isDownloaded = fileIsDownloaded();
115
                }
116
                this.downloadButton = (Button) findViewById(R.id.download_button);
117
                if ( isDownloaded )  {
118
                        downloadButton.setText("Open File");
119
                } else {
120
                        downloadButton.setText("Download File");
121
                }           
122
                downloadButton.setOnClickListener(new MyOnClickListener());
123
                
124
                if(app.isDeletingObject()){
125
                        deleteObjTask = new DeleteObjectListenerTask();
126
                        deleteObjTask.execute();
127
                }
128
                
129
                if(app.isDownloadingObject()){
130
                        downloadObjTask = new DownloadObjectListenerTask();
131
                        downloadObjTask.execute();
132
                }
133
                
134
        }
135
        
136
        
137
        
138
        @Override
139
        protected void onStop(){
140
                super.onStop();
141

    
142
                /*
143
                 * Need to stop running listener task
144
                 * if we exit
145
                 */
146
                if(deleteObjTask != null){
147
                        deleteObjTask.cancel(true);
148
                }
149
                
150
                if(downloadObjTask != null){
151
                        downloadObjTask.cancel(true);
152
                }
153
        }
154

    
155

    
156
        private void loadObjectData() {
157
                //Object Name
158
                TextView name = (TextView) findViewById(R.id.view_container_name);
159
                name.setText(objects.getCName().toString());
160

    
161
                //File size
162
                if (objects.getBytes() >= bConver) {
163
                        megaBytes = Math.abs(objects.getBytes()/bConver + 0.2);
164
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
165
                        sublabel.setText(megaBytes + " MB");
166
                } else if (objects.getBytes() >= kbConver){
167
                        kiloBytes = Math.abs(objects.getBytes()/kbConver + 0.2);
168
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
169
                        sublabel.setText(kiloBytes + " KB");
170
                } else {
171
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
172
                        sublabel.setText(objects.getBytes() + " B");
173
                }        
174

    
175
                //Content Type
176
                TextView cType = (TextView) findViewById(R.id.view_content_type);
177
                cType.setText(objects.getContentType().toString());
178

    
179
                //Last Modification date
180
                String strDate = objects.getLastMod();
181
                strDate = strDate.substring(0, strDate.indexOf('T'));
182

    
183
                TextView lastmod = (TextView) findViewById(R.id.view_file_modification);
184
                lastmod.setText(strDate);              
185
                rebuildMetadataList();
186
        }
187
        
188
        private void rebuildMetadataList(){
189
                LayoutInflater layoutInflater = LayoutInflater.from(ContainerObjectDetails.this);
190
                final LinearLayout metadata = (LinearLayout) findViewById(R.id.metadataList);
191
                if(metadata.getChildCount()>0)
192
                        metadata.removeViews(0,metadata.getChildCount());
193
                metadata.removeAllViews();
194
                
195
                if(objects.getMetadata()!=null){
196
                        int i=0;
197
                        Iterator<Entry<String,String>> it = objects.getMetadata().entrySet().iterator();
198
                        while (it.hasNext()) {
199
                                final Entry<String,String> perm = it.next();
200
                                final View v = layoutInflater.inflate(R.layout.metadatarow, null);
201
                                populateMetadataList(perm, v, metadata, i);
202
                                i++;
203
                        }
204
                }
205
        }
206
        
207
        private void populateMetadataList(final Entry<String,String>  metadata, final View v, final LinearLayout properties, int i){
208
                properties.addView(v, i);
209
                Log.d(LOG,i+" "+metadata.getKey()+" "+metadata.getValue());
210
                ((TextView) v.findViewById(R.id.mkey)).setText(metadata.getKey());
211
                ((TextView) v.findViewById(R.id.mvalue)).setText(metadata.getValue());
212
        }
213

    
214
        private class MyOnClickListener implements View.OnClickListener {
215
                @Override
216
                public void onClick(View v) {
217
                        if(v.equals(findViewById(R.id.preview_button))){
218
                                Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(cdnURL + "/" + objects.getCName()));
219
                                startActivity(viewIntent);  
220
                        }
221
                        /*
222
                         * need to perform different functions based on if
223
                         * the file is in the devices filesystem
224
                         */
225
                        if(v.equals(findViewById(R.id.download_button))){
226
                                if(!isDownloaded){
227
                                        if(storageIsReady()){
228
                                                new ContainerObjectDownloadTask().execute();
229
                                        }
230
                                        else{
231
                                                showAlert("Error", "Storage not found.");
232
                                        }
233
                                }
234
                                else{
235
                                        openFile();
236
                                }
237
                        }
238
                }
239
        }
240

    
241
        //Create the Menu options
242
        @Override 
243
        public boolean onCreateOptionsMenu(Menu menu) {
244
                super.onCreateOptionsMenu(menu);
245
                MenuInflater inflater = getMenuInflater();
246
                inflater.inflate(R.menu.container_object_list_menu, menu);
247
                return true;
248
        } 
249

    
250
        @Override 
251
        public boolean onOptionsItemSelected(MenuItem item) {
252
                switch (item.getItemId()) {
253
                case R.id.delete_object:
254
                        showDialog(deleteObject); 
255
                        return true;
256
                case R.id.refresh:
257
                        loadObjectData();
258
                        return true;
259
                }
260
                return false;
261
        } 
262

    
263
        @Override
264
        protected Dialog onCreateDialog(int id ) {
265
                switch (id) {
266
                case deleteObject:
267
                        return new AlertDialog.Builder(ContainerObjectDetails.this)
268
                        .setIcon(R.drawable.alert_dialog_icon)
269
                        .setTitle("Delete File")
270
                        .setMessage("Are you sure you want to delete this file?")
271
                        .setPositiveButton("Delete File", new DialogInterface.OnClickListener() {
272
                                public void onClick(DialogInterface dialog, int whichButton) {
273
                                        // User clicked OK so do some stuff
274
                                        trackEvent(GoogleAnalytics.CATEGORY_FILE, GoogleAnalytics.EVENT_DELETE, "", -1);
275
                                        new ContainerObjectDeleteTask().execute((Void[]) null);
276
                                }
277
                        })
278
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
279
                                public void onClick(DialogInterface dialog, int whichButton) {
280
                                        // User clicked Cancel so do some stuff
281
                                }
282
                        })
283
                        .create();
284
                }
285
                return null;
286
        }
287
        /**
288
         * @return the file
289
         */
290
        public ContainerObjects getViewFile() {
291
                return objects;
292
        }
293

    
294
        /**
295
         * @param File the file to set
296
         */
297
        public void setViewFile(ContainerObjects object) {
298
                this.objects = object;
299
        }
300

    
301
        /*
302
         * returns false if external storage is not avaliable
303
         * (if its mounted, missing, read-only, etc)
304
         * from: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
305
         */
306
        private boolean storageIsReady(){
307
                boolean mExternalStorageAvailable = false;
308
                boolean mExternalStorageWriteable = false;
309
                String state = Environment.getExternalStorageState();
310

    
311
                if (Environment.MEDIA_MOUNTED.equals(state)) {
312
                        // We can read and write the media
313
                        mExternalStorageAvailable = mExternalStorageWriteable = true;
314
                } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
315
                        // We can only read the media
316
                        mExternalStorageAvailable = true;
317
                        mExternalStorageWriteable = false;
318
                } else {
319
                        // Something else is wrong. It may be one of many other states, but all we need
320
                        //  to know is we can neither read nor write
321
                        mExternalStorageAvailable = mExternalStorageWriteable = false;
322
                }
323
                return mExternalStorageAvailable && mExternalStorageWriteable;
324
        }
325

    
326
        private boolean fileIsDownloaded(){
327
                if(storageIsReady()){
328
                        String fileName = Environment.getExternalStorageDirectory().getPath() + "/RackspaceCloud/" + objects.getCName();
329
                        File f = new File(fileName);
330
                        return f.isFile();
331
                }
332
                return false;
333
        }
334

    
335
        private void openFile(){
336
                File object = new File(Environment.getExternalStorageDirectory().getPath() + "/RackspaceCloud/" + objects.getCName());
337
                Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
338
                File file = new File(object.getAbsolutePath()); 
339
                String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
340
                String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
341
                myIntent.setDataAndType(Uri.fromFile(file),mimetype);
342
                //myIntent.setData(Uri.fromFile(file));
343
                try{
344
                        startActivity(myIntent);
345
                }
346
                catch(Exception e){
347
                        Toast.makeText(this, "Could not open file.", Toast.LENGTH_SHORT).show();
348
                }
349
        }
350

    
351
        private boolean writeFile(byte[] data){
352
                String directoryName = Environment.getExternalStorageDirectory().getPath() + DOWNLOAD_DIRECTORY;
353
                File f = new File(directoryName);
354

    
355
                if(!f.isDirectory()){
356
                        if(!f.mkdir()){
357
                                return false;
358
                        }
359
                }
360

    
361
                String filename = directoryName + "/" + objects.getCName();
362
                File object = new File(filename);
363
                BufferedOutputStream bos = null;
364

    
365
                try{
366
                        FileOutputStream fos = new FileOutputStream(object);
367
                        bos = new BufferedOutputStream(fos);
368
                        bos.write(data);
369
                }
370
                catch(FileNotFoundException e){
371
                        e.printStackTrace();
372
                }
373
                catch(IOException e){
374
                        e.printStackTrace();
375
                }
376
                finally{
377
                        if(bos != null){
378
                                try {
379
                                        bos.flush();
380
                                        bos.close();
381
                                } catch (IOException e) {
382
                                        // TODO Auto-generated catch block
383
                                        e.printStackTrace();
384
                                }
385
                        }
386
                }
387
                return true;
388
        }
389

    
390
        //Task's
391

    
392
        private class ContainerObjectDeleteTask extends AsyncTask<Void, Void, HttpBundle> {
393

    
394
                private CloudServersException exception;
395

    
396
                protected void onPreExecute(){
397
                        showDialog();
398
                        app.setDeleteingObject(true);
399
                        deleteObjTask = new DeleteObjectListenerTask();
400
                        deleteObjTask.execute();
401
                }
402

    
403
                @Override
404
                protected HttpBundle doInBackground(Void... arg0) {
405
                        HttpBundle bundle = null;        
406
                        try {
407
                                bundle = (new ContainerObjectManager(getContext())).deleteObject(containerNames, objects.getCName() );
408
                        } catch (CloudServersException e) {
409
                                exception = e;
410
                        }
411
                        
412
                        return bundle;
413
                }
414

    
415
                @Override
416
                protected void onPostExecute(HttpBundle bundle) {
417
                        app.setDeleteingObject(false);
418
                        hideDialog();
419
                        HttpResponse response = bundle.getResponse();
420
                        if (response != null) {
421
                                int statusCode = response.getStatusLine().getStatusCode();
422
                                if (statusCode == 204) {
423
                                        //handled by listener
424
                                } else {
425
                                        CloudServersException cse = parseCloudServersException(response);
426
                                        if ("".equals(cse.getMessage())) {
427
                                                showError("There was a problem deleting your File.", bundle);
428
                                        } else {
429
                                                showError("There was a problem deleting your file: " + cse.getMessage(), bundle);
430
                                        }
431
                                }
432
                        } else if (exception != null) {
433
                                showError("There was a problem deleting your file: " + exception.getMessage(), bundle);                                
434
                        }                        
435
                }
436
        }
437

    
438
        private class ContainerObjectDownloadTask extends AsyncTask<Void, Void, HttpBundle> {
439

    
440
                private CloudServersException exception;
441

    
442
                @Override
443
                protected void onPreExecute(){
444
                        showDialog();
445
                        app.setDownloadingObject(true);
446
                        downloadObjTask = new DownloadObjectListenerTask();
447
                        downloadObjTask.execute();
448
                }
449

    
450
                @Override
451
                protected HttpBundle doInBackground(Void... arg0) {
452
                        HttpBundle bundle = null;        
453
                        try {
454
                                bundle = (new ContainerObjectManager(getContext())).getObject(containerNames, objects.getCName());
455
                        } catch (CloudServersException e) {
456
                                exception = e;
457
                        }
458
                        return bundle;
459
                }
460

    
461
                @Override
462
                protected void onPostExecute(HttpBundle bundle) {
463
                        app.setDownloadingObject(false);
464
                        hideDialog();
465
                        HttpResponse response = bundle.getResponse();
466
                        if (response != null) {
467
                                int statusCode = response.getStatusLine().getStatusCode();
468
                                if (statusCode == 200) {
469
                                        setResult(Activity.RESULT_OK);
470
                                        HttpEntity entity = response.getEntity();
471
                                        app.setDownloadedEntity(entity);
472
                                } else {
473
                                        CloudServersException cse = parseCloudServersException(response);
474
                                        if ("".equals(cse.getMessage())) {
475
                                                showError("There was a problem downloading your File.", bundle);
476
                                        } else {
477
                                                showError("There was a problem downloading your file: " + cse.getMessage(), bundle);
478
                                        }
479
                                }
480
                        } else if (exception != null) {
481
                                showError("There was a problem downloading your file: " + exception.getMessage(), bundle);                                
482
                        }                        
483
                }
484
        }
485
        
486
        private class DeleteObjectListenerTask extends
487
        AsyncTask<Void, Void, Void> {
488
                
489
                @Override
490
                protected Void doInBackground(Void... arg1) {
491

    
492
                        while(app.isDeletingObject()){
493
                                // wait for process to finish
494
                                // or have it be canceled
495
                                if(deleteObjTask.isCancelled()){
496
                                        return null;
497
                                }
498
                        }
499
                        return null;
500
                }
501

    
502
                /*
503
                 * when no longer processing, time to load
504
                 * the new files
505
                 */
506
                @Override
507
                protected void onPostExecute(Void arg1) {
508
                        hideDialog();
509
                        setResult(99);
510
                        finish();
511
                }
512
        }
513
        
514
        private class DownloadObjectListenerTask extends
515
        AsyncTask<Void, Void, Void> {
516
                
517
                @Override
518
                protected Void doInBackground(Void... arg1) {
519

    
520
                        while(app.isDownloadingObject()){
521
                                // wait for process to finish
522
                                // or have it be canceled
523
                                if(downloadObjTask.isCancelled()){
524
                                        return null;
525
                                }
526
                        }
527
                        return null;
528
                }
529

    
530
                /*
531
                 * when no longer processing, time to load
532
                 * the new files
533
                 */
534
                @Override
535
                protected void onPostExecute(Void arg1) {
536
                        hideDialog();
537
                        try {
538
                                if(writeFile(EntityUtils.toByteArray(app.getDownloadedEntity()))){
539
                                        downloadButton.setText("Open File");
540
                                        isDownloaded = true;
541
                                }
542
                                else{
543
                                        showAlert("Error", "There was a problem downloading your file.");
544
                                }
545

    
546
                        } catch (IOException e) {
547
                                showAlert("Error", "There was a problem downloading your file.");
548
                                e.printStackTrace();
549
                        } catch (Exception e) {
550
                                showAlert("Error", "There was a problem downloading your file.");
551
                                e.printStackTrace();
552
                        }
553
                }
554
        }
555

    
556
}