Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / ContainerObjectDetails.java @ 08922f29

History | View | Annotate | Download (33.9 kB)

1
package com.rackspace.cloud.android;
2

    
3
import java.io.BufferedOutputStream;
4
import java.io.File;
5
import java.io.FileOutputStream;
6
import java.io.IOException;
7
import java.io.InputStream;
8
import java.io.OutputStream;
9
import java.util.ArrayList;
10
import java.util.HashMap;
11
import java.util.Iterator;
12
import java.util.List;
13
import java.util.Map;
14
import java.util.Map.Entry;
15
import java.util.StringTokenizer;
16

    
17
import org.apache.http.HttpEntity;
18
import org.apache.http.HttpResponse;
19

    
20
import android.app.Activity;
21
import android.app.AlertDialog;
22
import android.app.Dialog;
23
import android.content.DialogInterface;
24
import android.content.Intent;
25
import android.graphics.Color;
26
import android.net.Uri;
27
import android.os.AsyncTask;
28
import android.os.Bundle;
29
import android.os.Environment;
30
import android.util.Log;
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.View.OnClickListener;
37
import android.widget.Button;
38
import android.widget.CheckBox;
39
import android.widget.CompoundButton;
40
import android.widget.CompoundButton.OnCheckedChangeListener;
41
import android.widget.EditText;
42
import android.widget.ImageButton;
43
import android.widget.LinearLayout;
44
import android.widget.TabHost;
45
import android.widget.TextView;
46
import android.widget.Toast;
47

    
48
import com.rackspace.cloud.files.api.client.Container;
49
import com.rackspace.cloud.files.api.client.ContainerObjectManager;
50
import com.rackspace.cloud.files.api.client.ContainerObjects;
51
import com.rackspace.cloud.files.api.client.GroupResource;
52
import com.rackspace.cloud.files.api.client.ObjectVersion;
53
import com.rackspace.cloud.files.api.client.Permission;
54
import com.rackspace.cloud.servers.api.client.CloudServersException;
55
import com.rackspace.cloud.servers.api.client.http.HttpBundle;
56

    
57
/**
58
 * 
59
 * @author Phillip Toohill
60
 * 
61
 */
62

    
63
public class ContainerObjectDetails extends CloudActivity {
64
        private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
65
        private static final int deleteObject = 0;
66
        private static final int restoreVersion = 1;
67
        private final String DOWNLOAD_DIRECTORY = "PithosPlus";
68

    
69
        private ContainerObjects objects;
70
        private String containerNames;
71
        private String cdnURL;
72
        private String cdnEnabled;
73
        public String LOG = "ViewObject";
74
        private int bConver = 1048576;
75
        private int kbConver = 1024;
76
        private double megaBytes;
77
        private double kiloBytes;
78
        public Button previewButton;
79
        public Button downloadButton;
80
        private Boolean isDownloaded;
81
        private AndroidCloudApplication app;
82
        private DeleteObjectListenerTask deleteObjTask;
83
        private DownloadObjectListenerTask downloadObjTask;
84
        private List<ObjectVersion> versions = new ArrayList<ObjectVersion>();
85
        private boolean isReadOnly = false;
86
        private final List<String> metadataRemoved = new ArrayList<String>();
87
        private final Map<String,String> metadataAdded = new HashMap<String, String>();
88
        
89
        /** Called when the activity is first created. */
90
        @Override
91
        public void onCreate(Bundle savedInstanceState) {
92
                super.onCreate(savedInstanceState);
93
                trackPageView(GoogleAnalytics.PAGE_STORAGE_OBJECT);
94

    
95
                objects = (ContainerObjects) this.getIntent().getExtras()
96
                                .get("container");
97
                containerNames = (String) this.getIntent().getExtras()
98
                                .get("containerNames");
99
                cdnURL = (String) this.getIntent().getExtras().get("cdnUrl");
100
                cdnEnabled = (String) this.getIntent().getExtras().get("isCdnEnabled");
101
                
102
                setContentView(R.layout.viewobject);
103
                TabHost tabs = (TabHost) findViewById(R.id.tabhost2);
104

    
105
                tabs.setup();
106

    
107
                TabHost.TabSpec spec = tabs.newTabSpec("tag1");
108

    
109
                spec.setContent(R.id.details);
110
                spec.setIndicator("Details");
111
                tabs.addTab(spec);
112

    
113
                spec = tabs.newTabSpec("tag2");
114
                spec.setContent(R.id.metadata);
115
                spec.setIndicator("Metadata");
116
                tabs.addTab(spec);
117

    
118
                spec = tabs.newTabSpec("tag3");
119
                spec.setContent(R.id.sharing);
120
                spec.setIndicator("Sharing");
121
                tabs.addTab(spec);
122

    
123
                spec = tabs.newTabSpec("tag4");
124
                spec.setContent(R.id.versions);
125
                spec.setIndicator("Versions");
126
                tabs.addTab(spec);
127

    
128
                restoreState(savedInstanceState);
129
        }
130

    
131
        public boolean isFolder(){
132
                return objects.getContentType().startsWith("application/folder")||objects.getContentType().startsWith("application/directory");
133
        }
134
        @Override
135
        protected void onSaveInstanceState(Bundle outState) {
136
                super.onSaveInstanceState(outState);
137
                outState.putSerializable("container", objects);
138
                outState.putBoolean("isDownloaded", isDownloaded);
139
        }
140

    
141
        protected void restoreState(Bundle state) {
142
                super.restoreState(state);
143
                /*
144
                 * need reference to the app so you can access curDirFiles as well as
145
                 * processing status
146
                 */
147
                app = (AndroidCloudApplication) this.getApplication();
148

    
149
                if (state != null && state.containsKey("container")) {
150
                        objects = (ContainerObjects) state.getSerializable("container");
151
                }
152
                loadObjectData();
153

    
154
                if (cdnEnabled.equals("true")) {
155
                        this.previewButton = (Button) findViewById(R.id.preview_button);
156
                        previewButton.setOnClickListener(new MyOnClickListener());
157
                } else {
158
                        this.previewButton = (Button) findViewById(R.id.preview_button);
159
                        previewButton.setVisibility(View.GONE);
160
                }
161

    
162
                if (state != null && state.containsKey("isDownloaded")) {
163
                        isDownloaded = state.getBoolean("isDownloaded");
164
                } else {
165
                        isDownloaded = fileIsDownloaded();
166
                }
167
                this.downloadButton = (Button) findViewById(R.id.download_button);
168
                if (isDownloaded) {
169
                        downloadButton.setText("Open File");
170
                } else {
171
                        downloadButton.setText("Download File");
172
                }
173
                downloadButton.setOnClickListener(new MyOnClickListener());
174

    
175
                if (app.isDeletingObject()) {
176
                        deleteObjTask = new DeleteObjectListenerTask();
177
                        deleteObjTask.execute();
178
                }
179

    
180
                if (app.isDownloadingObject()) {
181
                        downloadObjTask = new DownloadObjectListenerTask();
182
                        downloadObjTask.execute();
183
                }
184

    
185
        }
186

    
187
        @Override
188
        protected void onStop() {
189
                super.onStop();
190

    
191
                /*
192
                 * Need to stop running listener task if we exit
193
                 */
194
                if (deleteObjTask != null) {
195
                        deleteObjTask.cancel(true);
196
                }
197

    
198
                if (downloadObjTask != null) {
199
                        downloadObjTask.cancel(true);
200
                }
201
        }
202

    
203
        private void loadObjectData() {
204
                setTitle("Details: " +objects.getCName());
205
                metadataRemoved.clear();
206
                metadataAdded.clear();
207
                if(Container.MYSHARED.equals(objects.getContainerName())||Container.MYSHARED.equals(containerNames)){
208
                        isReadOnly = true;
209
                        
210
                }
211
                // Object Name
212
                TextView name = (TextView) findViewById(R.id.view_container_name);
213
                name.setText(objects.getCName().toString());
214

    
215
                // File size
216
                if (objects.getBytes() >= bConver) {
217
                        megaBytes = Math.abs(objects.getBytes() / bConver + 0.2);
218
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
219
                        sublabel.setText(megaBytes + " MB");
220
                } else if (objects.getBytes() >= kbConver) {
221
                        kiloBytes = Math.abs(objects.getBytes() / kbConver + 0.2);
222
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
223
                        sublabel.setText(kiloBytes + " KB");
224
                } else {
225
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
226
                        sublabel.setText(objects.getBytes() + " B");
227
                }
228

    
229
                // Content Type
230
                TextView cType = (TextView) findViewById(R.id.view_content_type);
231
                cType.setText(objects.getContentType().toString());
232

    
233
                // Last Modification date
234
                String strDate = objects.getLastMod();
235
                strDate = strDate.substring(0, strDate.indexOf('T'));
236

    
237
                TextView lastmod = (TextView) findViewById(R.id.view_file_modification);
238
                lastmod.setText(strDate);
239
                rebuildMetadataList();
240
                if(isFolder()){
241
                        findViewById(R.id.download_text).setVisibility(View.GONE);
242
                        findViewById(R.id.linearLayout1).setVisibility(View.GONE);
243
                        findViewById(R.id.layoutPublic).setVisibility(View.GONE);
244
                }
245
                rebuildPermissionList();
246
                try {
247
                        versions = new ContainerObjectManager(getApplicationContext())
248
                                        .getObjectVersions(objects.getContainerName(),
249
                                                        objects.getCName());
250
                        rebuildVersionList();
251
                } catch (CloudServersException e) {
252
                        // TODO Auto-generated catch block
253
                        e.printStackTrace();
254
                }
255
                
256
        }
257
        
258
        private void rebuildMetadataList() {
259
                Button newmetadata = (Button)findViewById(R.id.newMetadata);
260
                if(isReadOnly)
261
                        newmetadata.setVisibility(View.GONE);
262
                newmetadata.setOnClickListener(new OnClickListener() {
263
                        
264
                        @Override
265
                        public void onClick(View arg0) {
266
                                final AlertDialog.Builder alert = new AlertDialog.Builder(ContainerObjectDetails.this);
267
                                alert.setTitle("Add Metadata");
268
                                LinearLayout ll = new LinearLayout(ContainerObjectDetails.this);
269
                                ll.setOrientation(LinearLayout.VERTICAL);
270

    
271
                                final EditText input = new EditText(ContainerObjectDetails.this);
272
                                final EditText input2 = new EditText(ContainerObjectDetails.this);
273
                                ll.addView(input);
274
                                ll.addView(input2);
275
                                alert.setView(ll);
276
                                alert.setPositiveButton("Create", new DialogInterface.OnClickListener() {
277
                                        public void onClick(DialogInterface dialog, int whichButton) {
278
                                                String key = input.getText().toString().trim();
279
                                                String value = input2.getText().toString().trim();
280
                                                addMetatadata(key, value);
281
                                        }
282
                                });
283
                                
284
                                alert.setNegativeButton("Cancel",
285
                                                new DialogInterface.OnClickListener() {
286
                                        public void onClick(DialogInterface dialog, int whichButton) {
287
                                                dialog.cancel();
288
                                        }
289
                                });
290
                                alert.show();
291
                        }
292
                });
293
                LayoutInflater layoutInflater = LayoutInflater
294
                                .from(ContainerObjectDetails.this);
295
                final LinearLayout metadata = (LinearLayout) findViewById(R.id.metadataList);
296
                if (metadata.getChildCount() > 0)
297
                        metadata.removeViews(0, metadata.getChildCount());
298
                metadata.removeAllViews();
299

    
300
                if (objects.getMetadata() != null) {
301
                        int i = 0;
302
                        Iterator<Entry<String, String>> it = objects.getMetadata()
303
                                        .entrySet().iterator();
304
                        while (it.hasNext()) {
305
                                final Entry<String, String> perm = it.next();
306
                                final View v = layoutInflater.inflate(R.layout.metadatarow,
307
                                                null);
308
                                populateMetadataList(perm, v, metadata, i);
309
                                i++;
310
                        }
311
                }
312
        }
313
        
314
        private void addMetatadata(String key, String value){
315
                if(objects.getMetadata()==null)
316
                        objects.setMetadata(new HashMap<String, String>());
317
                metadataAdded.put(key,value);
318
                objects.getMetadata().put(key, value);
319
                rebuildMetadataList();
320
        }
321

    
322
        private void populateMetadataList(final Entry<String, String> metadata,
323
                        final View v, final LinearLayout properties, int i) {
324
                properties.addView(v, i);
325
                Log.d(LOG, i + " " + metadata.getKey() + " " + metadata.getValue());
326
                ((TextView) v.findViewById(R.id.mkey)).setText(metadata.getKey());
327
                ((TextView) v.findViewById(R.id.mvalue)).setText(metadata.getValue());
328
                if(isReadOnly)
329
                        v.findViewById(R.id.remove).setVisibility(View.GONE);
330
                ((ImageButton) v.findViewById(R.id.remove))
331
                .setOnClickListener(new OnClickListener() {
332

    
333
                        @Override
334
                        public void onClick(View v1) {
335
                                properties.removeView(v);
336
                                metadataRemoved.add(metadata.getKey());
337
                                objects.getMetadata().remove(metadata.getKey());
338
                                
339

    
340
                        }
341
                });
342
        }
343

    
344
        private void rebuildPermissionList() {
345
                Button newmetadata = (Button)findViewById(R.id.newPermission);
346
                CheckBox readForAll = (CheckBox)findViewById(R.id.folderPublic);
347
                if(isReadOnly){
348
                        newmetadata.setVisibility(View.GONE);
349
                        readForAll.setEnabled(false);
350
                }
351
                objects.setPublicf(objects.getIsPublic()!=null);
352
                readForAll.setChecked(objects.isPublicf());
353

    
354
                readForAll.setOnCheckedChangeListener(new OnCheckedChangeListener() {
355

    
356
                                        @Override
357
                                        public void onCheckedChanged(CompoundButton buttonView,
358
                                                        boolean isChecked) {
359
                                                objects.setPublicf(isChecked);
360

    
361
                                        }
362
                                });
363
                newmetadata.setOnClickListener(new OnClickListener() {
364

    
365
                        @Override
366
                        public void onClick(View v) {
367
                                showAddDialog();                                
368
                        }
369
                        
370
                });
371
                LayoutInflater layoutInflater = LayoutInflater
372
                                .from(ContainerObjectDetails.this);
373
                final LinearLayout properties = (LinearLayout) findViewById(R.id.permissionsList);
374
                if (properties.getChildCount() > 0)
375
                        properties.removeViews(0, properties.getChildCount());
376
                properties.removeAllViews();
377
                Iterator<Permission> it = null;
378
                if (objects.getPermissions() != null) {
379
                        it = objects.getPermissions().iterator();
380
                        int i = 0;
381
                        while (it.hasNext()) {
382
                                final Permission perm = it.next();
383
                                final View v = layoutInflater.inflate(R.layout.propertiesrow,
384
                                                null);
385
                                populatePermissionList(perm, v, properties, i);
386
                                i++;
387
                        }
388
                }
389
        }
390

    
391
        private void populatePermissionList(final Permission perm, final View v,
392
                        final LinearLayout properties, int i) {
393

    
394
                properties.addView(v, i);
395
                if(isReadOnly){
396
                        v.findViewById(R.id.remove).setVisibility(View.GONE);
397
                        ((CheckBox) v.findViewById(R.id.read)).setEnabled(false);
398
                        ((CheckBox) v.findViewById(R.id.write)).setEnabled(false);
399
                }
400
                
401
                ((TextView) v.findViewById(R.id.ownerName)).setText(perm.getUser()==null?perm.getGroup()+":":perm.getUser());
402
                ((CheckBox) v.findViewById(R.id.read)).setChecked(perm.isRead());
403
                ((CheckBox) v.findViewById(R.id.write)).setChecked(perm.isWrite());
404

    
405
                ((CheckBox) v.findViewById(R.id.read))
406
                                .setOnCheckedChangeListener(new OnCheckedChangeListener() {
407

    
408
                                        @Override
409
                                        public void onCheckedChanged(CompoundButton buttonView,
410
                                                        boolean isChecked) {
411
                                                perm.setRead(isChecked);
412

    
413
                                        }
414
                                });
415
                ((CheckBox) v.findViewById(R.id.write))
416
                                .setOnCheckedChangeListener(new OnCheckedChangeListener() {
417

    
418
                                        @Override
419
                                        public void onCheckedChanged(CompoundButton buttonView,
420
                                                        boolean isChecked) {
421
                                                perm.setWrite(isChecked);
422

    
423
                                        }
424
                                });
425
                ((Button) v.findViewById(R.id.remove))
426
                                .setOnClickListener(new OnClickListener() {
427

    
428
                                        @Override
429
                                        public void onClick(View v1) {
430
                                                properties.removeView(v);
431
                                                objects.getPermissions().remove(perm);
432

    
433
                                        }
434
                                });
435
        }
436
        
437
        private void addPermission(boolean group, String userOrGroup){
438
                if(objects.getPermissions()==null)
439
                        objects.setPermissions(new ArrayList<Permission>());
440
                Permission np = new Permission();
441
                if(group)
442
                        np.setGroup(userOrGroup);
443
                else
444
                        np.setUser(userOrGroup);
445
                objects.getPermissions().add(np);
446
                rebuildPermissionList();
447
        }
448
        private void showAddDialog(){
449
                final CharSequence[] items = {"Add User", "Add Group"};
450

    
451
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
452
                builder.setTitle("User Or Group");
453
                builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
454
                    public void onClick(DialogInterface dialog, int item) {
455
                            boolean user;
456
                       if(item ==0){
457
                               user=true;
458
                       }
459
                       else
460
                               user=false;
461
                       populateAddDialog(user);
462
                       dialog.dismiss();
463
                       
464
                    }
465
                });
466
                AlertDialog alert2 = builder.create();
467
                alert2.show();
468
                
469
        }
470
        
471
        private void populateAddDialog(final boolean user){
472
                final AlertDialog.Builder alert = new AlertDialog.Builder(ContainerObjectDetails.this);
473
               if(user){
474
                       alert.setTitle("Add User");
475
                       final EditText input = new EditText(ContainerObjectDetails.this);
476
                input.setTextColor(Color.BLACK);
477
                    
478
                    alert.setView(input);
479
                    
480
                    alert.setPositiveButton("Add", new DialogInterface.OnClickListener() {
481
                            public void onClick(DialogInterface dialog, int whichButton) {
482
                                    String value = input.getText().toString().trim();
483
                                    addPermission(false, value);
484
                                    
485
                            }
486
                    });
487

    
488
                    alert.setNegativeButton("Cancel",
489
                                    new DialogInterface.OnClickListener() {
490
                                            public void onClick(DialogInterface dialog, int whichButton) {
491
                                                    dialog.cancel();
492
                                            
493
                                            }
494
                                    });
495
                    alert.show();
496
               }
497
               else{
498
                       AlertDialog.Builder builder = new AlertDialog.Builder(this);
499
                    builder.setTitle("Add Group");
500
                    builder.setSingleChoiceItems(getGroupNames().toArray(new String[0]), -1, new DialogInterface.OnClickListener() {
501
                        public void onClick(DialogInterface dialog, int item) {
502
                                addPermission(true, getGroupNames().get(item));
503
                           dialog.dismiss();
504
                           
505
                        }
506
                    });
507
                    AlertDialog alert2 = builder.create();
508
                    alert2.show();
509
               }
510
            
511
        }
512
        
513
        public List<String> getGroupNames(){
514
                List<String> result = new ArrayList<String>();
515
                List<GroupResource> groups = ((AndroidCloudApplication)getApplication()).getGroups();
516
                for(GroupResource g : groups){
517
                        result.add(g.getName());
518
                }
519
                return result;
520
        }
521
        
522
        private void rebuildVersionList() {
523
                LayoutInflater layoutInflater = LayoutInflater
524
                                .from(ContainerObjectDetails.this);
525
                final LinearLayout properties = (LinearLayout) findViewById(R.id.versionsList);
526
                if (properties.getChildCount() > 0)
527
                        properties.removeViews(0, properties.getChildCount());
528
                properties.removeAllViews();
529
                Iterator<ObjectVersion> it;
530
                // Collections.reverse(versions);
531
                it = versions.iterator();
532
                int i = 0;
533
                while (it.hasNext()) {
534
                        final ObjectVersion perm = it.next();
535
                        final View v = layoutInflater.inflate(R.layout.versionsrow, null);
536
                        populateVersionList(perm, v, properties, i);
537
                        i++;
538
                }
539
        }
540
        String selectedVersion=null;
541
        private void populateVersionList(final ObjectVersion perm, final View v,
542
                        final LinearLayout properties, int i) {
543

    
544
                properties.addView(v, i);
545

    
546
                ((TextView) v.findViewById(R.id.versionName)).setText("Version: "
547
                                + perm.getVersion());
548
                
549
                ((TextView) v.findViewById(R.id.versionModified)).setText("Modified: "
550
                                + perm.getDateString());
551
                if (versions.size() == 1 || isReadOnly) {
552
                        // ((Button)
553
                        // v.findViewById(R.id.vremove)).setVisibility(View.INVISIBLE);
554
                        ((Button) v.findViewById(R.id.vrestore))
555
                                        .setVisibility(View.INVISIBLE);
556
                }
557
                /*
558
                 * ((Button) v.findViewById(R.id.vremove)) .setOnClickListener(new
559
                 * OnClickListener() {
560
                 * 
561
                 * @Override public void onClick(View v1) { Log.d("PERMS",
562
                 * perm.getUri()); try { new GssHttpCommands(getDroidApplication()
563
                 * .getUserDetails
564
                 * ()).deleteFolder(perm.getUri()+"?version="+perm.getVersion()); }
565
                 * catch (SystemErrorException e) { // TODO Auto-generated catch block
566
                 * e.printStackTrace(); } catch (GssHttpException e) { // TODO
567
                 * Auto-generated catch block e.printStackTrace(); }
568
                 * getFileTask().execute(res.getUri()); //properties.removeView(v);
569
                 * 
570
                 * } });
571
                 */
572
                ((Button) v.findViewById(R.id.vrestore))
573
                                .setOnClickListener(new OnClickListener() {
574

    
575
                                        @Override
576
                                        public void onClick(View v1) {
577
                                                selectedVersion = String.valueOf(perm.getVersion());
578
                                                showDialog(restoreVersion);
579

    
580
                                        }
581
                                });
582
                ((Button) v.findViewById(R.id.vdownload))
583
                                .setOnClickListener(new OnClickListener() {
584

    
585
                                        @Override
586
                                        public void onClick(View v1) {
587

    
588
                                                // getDownloadTask().execute(perm.getUri()+"?version="+perm.getVersion());
589
                                                // properties.removeView(v);
590

    
591
                                        }
592
                                });
593
        }
594

    
595
        private class MyOnClickListener implements View.OnClickListener {
596
                @Override
597
                public void onClick(View v) {
598
                        if (v.equals(findViewById(R.id.preview_button))) {
599
                                Intent viewIntent = new Intent("android.intent.action.VIEW",
600
                                                Uri.parse(cdnURL + "/" + objects.getCName()));
601
                                startActivity(viewIntent);
602
                        }
603
                        /*
604
                         * need to perform different functions based on if the file is in
605
                         * the devices filesystem
606
                         */
607
                        if (v.equals(findViewById(R.id.download_button))) {
608
                                if (!isDownloaded) {
609
                                        if (storageIsReady()) {
610
                                                new ContainerObjectDownloadTask().execute();
611
                                        } else {
612
                                                showAlert("Error", "Storage not found.");
613
                                        }
614
                                } else {
615
                                        openFile();
616
                                }
617
                        }
618
                }
619
        }
620

    
621
        // Create the Menu options
622
        @Override
623
        public boolean onCreateOptionsMenu(Menu menu) {
624
                super.onCreateOptionsMenu(menu);
625
                MenuInflater inflater = getMenuInflater();
626
                inflater.inflate(R.menu.container_object_list_menu, menu);
627
                menu.findItem(R.id.delete_object).setVisible(!isReadOnly);
628
                menu.findItem(R.id.save).setVisible(!isReadOnly);
629
                return true;
630
        }
631

    
632
        @Override
633
        public boolean onOptionsItemSelected(MenuItem item) {
634
                switch (item.getItemId()) {
635
                case R.id.delete_object:
636
                        showDialog(deleteObject);
637
                        return true;
638
                case R.id.refresh:
639
                        loadObjectData();
640
                        return true;
641
                case R.id.save:
642
                        new ContainerObjectUpdateTask().execute();
643
                        return true;
644
                }
645
                return false;
646
        }
647

    
648
        @Override
649
        protected Dialog onCreateDialog(int id) {
650
                switch (id) {
651
                case deleteObject:
652
                        return new AlertDialog.Builder(ContainerObjectDetails.this)
653
                                        .setIcon(R.drawable.alert_dialog_icon)
654
                                        .setTitle("Delete File")
655
                                        .setMessage("Are you sure you want to delete this file?")
656
                                        .setPositiveButton("Delete File",
657
                                                        new DialogInterface.OnClickListener() {
658
                                                                public void onClick(DialogInterface dialog,
659
                                                                                int whichButton) {
660
                                                                        // User clicked OK so do some stuff
661
                                                                        trackEvent(GoogleAnalytics.CATEGORY_FILE,
662
                                                                                        GoogleAnalytics.EVENT_DELETE, "",
663
                                                                                        -1);
664
                                                                        new ContainerObjectDeleteTask()
665
                                                                                        .execute((Void[]) null);
666
                                                                }
667
                                                        })
668
                                        .setNegativeButton("Cancel",
669
                                                        new DialogInterface.OnClickListener() {
670
                                                                public void onClick(DialogInterface dialog,
671
                                                                                int whichButton) {
672
                                                                        // User clicked Cancel so do some stuff
673
                                                                }
674
                                                        }).create();
675
                case restoreVersion:
676
                        return new AlertDialog.Builder(ContainerObjectDetails.this)
677
                                        .setIcon(R.drawable.alert_dialog_icon)
678
                                        .setTitle("Restore Version")
679
                                        .setMessage("Are you sure you want to restore this version?")
680
                                        .setPositiveButton("Restore Version",
681
                                                        new DialogInterface.OnClickListener() {
682
                                                                public void onClick(DialogInterface dialog,
683
                                                                                int whichButton) {
684
                                                                        // User clicked OK so do some stuff
685
                                                                        /*trackEvent(GoogleAnalytics.CATEGORY_FILE,
686
                                                                                        GoogleAnalytics.EVENT_DELETE, "",
687
                                                                                        -1);*/
688
                                                                        new VersionRestoreTask()
689
                                                                                        .execute(selectedVersion);
690
                                                                }
691
                                                        })
692
                                        .setNegativeButton("Cancel",
693
                                                        new DialogInterface.OnClickListener() {
694
                                                                public void onClick(DialogInterface dialog,
695
                                                                                int whichButton) {
696
                                                                        // User clicked Cancel so do some stuff
697
                                                                }
698
                                                        }).create();
699
                
700
                }
701
                
702
                return null;
703
        }
704

    
705
        /**
706
         * @return the file
707
         */
708
        public ContainerObjects getViewFile() {
709
                return objects;
710
        }
711

    
712
        /**
713
         * @param File
714
         *            the file to set
715
         */
716
        public void setViewFile(ContainerObjects object) {
717
                this.objects = object;
718
        }
719

    
720
        /*
721
         * returns false if external storage is not avaliable (if its mounted,
722
         * missing, read-only, etc) from:
723
         * http://developer.android.com/guide/topics/data
724
         * /data-storage.html#filesExternal
725
         */
726
        private boolean storageIsReady() {
727
                boolean mExternalStorageAvailable = false;
728
                boolean mExternalStorageWriteable = false;
729
                String state = Environment.getExternalStorageState();
730

    
731
                if (Environment.MEDIA_MOUNTED.equals(state)) {
732
                        // We can read and write the media
733
                        mExternalStorageAvailable = mExternalStorageWriteable = true;
734
                } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
735
                        // We can only read the media
736
                        mExternalStorageAvailable = true;
737
                        mExternalStorageWriteable = false;
738
                } else {
739
                        // Something else is wrong. It may be one of many other states, but
740
                        // all we need
741
                        // to know is we can neither read nor write
742
                        mExternalStorageAvailable = mExternalStorageWriteable = false;
743
                }
744
                return mExternalStorageAvailable && mExternalStorageWriteable;
745
        }
746

    
747
        private boolean fileIsDownloaded() {
748
                if (storageIsReady()) {
749
                        String fileName = Environment.getExternalStorageDirectory()
750
                                        .getPath() + "/PithosPlus/" + objects.getCName();
751
                        File f = new File(fileName);
752
                        return f.isFile();
753
                }
754
                return false;
755
        }
756

    
757
        private void openFile() {
758
                File object = new File(Environment.getExternalStorageDirectory()
759
                                .getPath() + "/PithosPlus/" + objects.getCName());
760
                Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
761
                File file = new File(object.getAbsolutePath());
762
                String extension = android.webkit.MimeTypeMap
763
                                .getFileExtensionFromUrl(Uri.fromFile(file).toString());
764
                String mimetype = android.webkit.MimeTypeMap.getSingleton()
765
                                .getMimeTypeFromExtension(extension);
766
                myIntent.setDataAndType(Uri.fromFile(file), mimetype);
767
                // myIntent.setData(Uri.fromFile(file));
768
                try {
769
                        startActivity(myIntent);
770
                } catch (Exception e) {
771
                        Toast.makeText(this, "Could not open file.", Toast.LENGTH_SHORT)
772
                                        .show();
773
                }
774
        }
775

    
776
        // Task's
777

    
778
        private class ContainerObjectDeleteTask extends
779
                        AsyncTask<Void, Void, HttpBundle> {
780

    
781
                private CloudServersException exception;
782

    
783
                protected void onPreExecute() {
784
                        showDialog();
785
                        app.setDeleteingObject(true);
786
                        deleteObjTask = new DeleteObjectListenerTask();
787
                        deleteObjTask.execute();
788
                }
789

    
790
                @Override
791
                protected HttpBundle doInBackground(Void... arg0) {
792
                        HttpBundle bundle = null;
793
                        try {
794
                                bundle = (new ContainerObjectManager(getContext()))
795
                                                .deleteObject(containerNames, objects.getCName());
796
                        } catch (CloudServersException e) {
797
                                exception = e;
798
                        }
799

    
800
                        return bundle;
801
                }
802

    
803
                @Override
804
                protected void onPostExecute(HttpBundle bundle) {
805
                        app.setDeleteingObject(false);
806
                        hideDialog();
807
                        HttpResponse response = bundle.getResponse();
808
                        if (response != null) {
809
                                int statusCode = response.getStatusLine().getStatusCode();
810
                                if (statusCode == 204) {
811
                                        // handled by listener
812
                                } else {
813
                                        CloudServersException cse = parseCloudServersException(response);
814
                                        if ("".equals(cse.getMessage())) {
815
                                                showError("There was a problem deleting your File.",
816
                                                                bundle);
817
                                        } else {
818
                                                showError("There was a problem deleting your file: "
819
                                                                + cse.getMessage(), bundle);
820
                                        }
821
                                }
822
                        } else if (exception != null) {
823
                                showError("There was a problem deleting your file: "
824
                                                + exception.getMessage(), bundle);
825
                        }
826
                }
827
        }
828

    
829
        private class ContainerObjectDownloadTask extends
830
                        AsyncTask<Void, Void, HttpBundle> {
831

    
832
                private CloudServersException exception;
833

    
834
                @Override
835
                protected void onPreExecute() {
836
                        showDialog();
837
                        app.setDownloadingObject(true);
838
                        downloadObjTask = new DownloadObjectListenerTask();
839
                        downloadObjTask.execute();
840
                }
841

    
842
                @Override
843
                protected HttpBundle doInBackground(Void... arg0) {
844
                        HttpBundle bundle = null;
845
                        try {
846
                                bundle = (new ContainerObjectManager(getContext())).getObject(
847
                                                containerNames, objects.getCName());
848
                        } catch (CloudServersException e) {
849
                                exception = e;
850
                        }
851
                        return bundle;
852
                }
853

    
854
                @Override
855
                protected void onPostExecute(HttpBundle bundle) {
856
                        
857
                        
858
                        HttpResponse response = bundle.getResponse();
859
                        if (response != null) {
860
                                int statusCode = response.getStatusLine().getStatusCode();
861
                                if (statusCode == 200) {
862
                                        setResult(Activity.RESULT_OK);
863
                                        HttpEntity entity = response.getEntity();
864
                                        app.setDownloadedEntity(entity);
865
                                } else {
866
                                        CloudServersException cse = parseCloudServersException(response);
867
                                        if ("".equals(cse.getMessage())) {
868
                                                showError("There was a problem downloading your File.",
869
                                                                bundle);
870
                                        } else {
871
                                                showError("There was a problem downloading your file: "
872
                                                                + cse.getMessage(), bundle);
873
                                        }
874
                                }
875
                        } else if (exception != null) {
876
                                showError("There was a problem downloading your file: "
877
                                                + exception.getMessage(), bundle);
878
                        }
879
                        app.setDownloadingObject(false);
880
                }
881
        }
882

    
883
        private class DeleteObjectListenerTask extends AsyncTask<Void, Void, Void> {
884

    
885
                @Override
886
                protected Void doInBackground(Void... arg1) {
887

    
888
                        while (app.isDeletingObject()) {
889
                                // wait for process to finish
890
                                // or have it be canceled
891
                                if (deleteObjTask.isCancelled()) {
892
                                        return null;
893
                                }
894
                        }
895
                        return null;
896
                }
897

    
898
                /*
899
                 * when no longer processing, time to load the new files
900
                 */
901
                @Override
902
                protected void onPostExecute(Void arg1) {
903
                        hideDialog();
904
                        setResult(99);
905
                        finish();
906
                }
907
        }
908

    
909
        private class DownloadObjectListenerTask extends
910
                        AsyncTask<Void, Void, Void> {
911

    
912
                @Override
913
                protected Void doInBackground(Void... arg1) {
914

    
915
                        while (app.isDownloadingObject()) {
916
                                // wait for process to finish
917
                                // or have it be canceled
918
                                if (downloadObjTask.isCancelled()) {
919
                                        return null;
920
                                }
921
                        }
922
                        return null;
923
                }
924

    
925
                /*
926
                 * when no longer processing, time to load the new files
927
                 */
928
                @Override
929
                protected void onPostExecute(Void arg1) {
930
                        
931
                        try {
932
                                //TODO: run in background
933
                                if (writeFile(app.getDownloadedEntity().getContent())) {
934
                                        downloadButton.setText("Open File");
935
                                        isDownloaded = true;
936
                                } else {
937
                                        showAlert("Error",
938
                                                        "There was a problem downloading your file.");
939
                                }
940

    
941
                        } catch (IOException e) {
942
                                showAlert("Error", "There was a problem downloading your file.");
943
                                e.printStackTrace();
944
                        } catch (Exception e) {
945
                                showAlert("Error", "There was a problem downloading your file.");
946
                                e.printStackTrace();
947
                        }
948
                        hideDialog();
949
                }
950
        }
951

    
952
        private boolean writeFile(InputStream in) {
953
                String directoryName = Environment.getExternalStorageDirectory()
954
                                .getPath();
955
                File f = new File(directoryName, DOWNLOAD_DIRECTORY);
956
                Log.i(LOG,directoryName);
957
                if (!f.isDirectory()) {
958
                        if (!f.mkdir()) {
959
                                return false;
960
                        }
961
                }
962
                Log.i(LOG,objects.toString());
963
                //String filename = directoryName + "/" + objects.getName();
964
                StringTokenizer str = new StringTokenizer(objects.getCName(),"/");
965
                String path="";
966
                String fname="";
967
                int count = str.countTokens();
968
                Log.i(LOG,"object is: "+objects.getCName()+" "+count);
969
                for(int i=0;i<count;i++){
970
                        if(i<(count-1)){
971
                                path = path+str.nextToken()+"/";
972
                        }
973
                        else
974
                                fname=str.nextToken();
975
                }
976
                Log.i(LOG,"Path is:"+path);
977
                Log.i(LOG,"Fname is:"+fname);
978
                File object;
979
                if("".equals(path)){
980
                        object = new File(f,fname);
981
                }
982
                else{
983
                        File t = new File(f,path);
984
                        t.mkdirs();
985
                        object = new File(t,fname);
986
                }
987
                
988
                
989
                BufferedOutputStream bos = null;
990

    
991
                try {
992
                        FileOutputStream fos = new FileOutputStream(object);
993
                        copy(in, fos);
994
                } catch (IOException e) {
995
                        e.printStackTrace();
996
                } finally {
997
                        if (bos != null) {
998
                                try {
999
                                        bos.flush();
1000
                                        bos.close();
1001
                                } catch (IOException e) {
1002
                                        // TODO Auto-generated catch block
1003
                                        e.printStackTrace();
1004
                                }
1005
                        }
1006
                }
1007
                return true;
1008
        }
1009

    
1010
        public static long copy(InputStream input, OutputStream output) throws IOException {
1011
                
1012
                byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
1013
                long count = 0;
1014
                int n = 0;
1015
                try{
1016
                        while (-1 != (n = input.read(buffer))) {
1017
                                output.write(buffer, 0, n);
1018
                                count += n;
1019
                                //monitor.setCurrent(count);
1020
                        }
1021
                }
1022
                finally{
1023
                        input.close();
1024
                        output.close();
1025
                }
1026
                return count;
1027
        }
1028
        
1029
        @Override
1030
        public void onBackPressed() {
1031
                
1032
                //TODO: perform update
1033
                super.onBackPressed();
1034
        }
1035
        
1036
        
1037
        
1038
        
1039
        private class ContainerObjectUpdateTask extends
1040
                        AsyncTask<Void, Void, HttpBundle> {
1041
                
1042
                private CloudServersException exception;
1043
                
1044
                protected void onPreExecute() {
1045
                        showDialog();
1046
                }
1047
                
1048
                @Override
1049
                protected HttpBundle doInBackground(Void... arg0) {
1050
                        HttpBundle bundle = null;
1051
                        try {
1052
                                bundle = saveObject();
1053
                        } catch (CloudServersException e) {
1054
                                exception = e;
1055
                        }
1056
                
1057
                        return bundle;
1058
                }
1059
                
1060
                @Override
1061
                protected void onPostExecute(HttpBundle bundle) {
1062
                        hideDialog();
1063
                        HttpResponse response = bundle.getResponse();
1064
                        if (response != null) {
1065
                                int statusCode = response.getStatusLine().getStatusCode();
1066
                                if (statusCode == 202) {
1067
                                        hideDialog();
1068
                                        setResult(99);
1069
                                        finish();
1070
                                } else {
1071
                                        CloudServersException cse = parseCloudServersException(response);
1072
                                        if ("".equals(cse.getMessage())) {
1073
                                                showError("There was a problem deleting your File.",
1074
                                                                bundle);
1075
                                        } else {
1076
                                                showError("There was a problem deleting your file: "
1077
                                                                + cse.getMessage(), bundle);
1078
                                        }
1079
                                }
1080
                        } else if (exception != null) {
1081
                                showError("There was a problem deleting your file: "
1082
                                                + exception.getMessage(), bundle);
1083
                        }
1084
                }
1085
        }
1086
        
1087
        private class VersionRestoreTask extends
1088
                                AsyncTask<String, Void, HttpBundle> {
1089
                        
1090
                        private CloudServersException exception;
1091
                        
1092
                        protected void onPreExecute() {
1093
                                showDialog();
1094
                        }
1095
                        
1096
                        @Override
1097
                        protected HttpBundle doInBackground(String... arg0) {
1098
                                HttpBundle bundle = null;
1099
                                try {
1100
                                        bundle = restoreVersion(arg0[0]);
1101
                                } catch (CloudServersException e) {
1102
                                        e.printStackTrace();
1103
                                        exception = e;
1104
                                }
1105
                        
1106
                                return bundle;
1107
                        }
1108
                        
1109
                        @Override
1110
                        protected void onPostExecute(HttpBundle bundle) {
1111
                                hideDialog();
1112
                                HttpResponse response = null;
1113
                                if(bundle!=null)
1114
                                        response= bundle.getResponse();
1115
                                if (response != null) {
1116
                                        int statusCode = response.getStatusLine().getStatusCode();
1117
                                        if (statusCode == 204||statusCode==202) {
1118
                                                hideDialog();
1119
                                                setResult(99);
1120
                                                finish();
1121
                                        } else {
1122
                                                CloudServersException cse = parseCloudServersException(response);
1123
                                                if ("".equals(cse.getMessage())) {
1124
                                                        showError("There was a problem deleting your File.",
1125
                                                                        bundle);
1126
                                                } else {
1127
                                                        showError("There was a problem deleting your file: "
1128
                                                                        + cse.getMessage(), bundle);
1129
                                                }
1130
                                        }
1131
                                } else if (exception != null) {
1132
                                        showError("There was a problem deleting your file: "
1133
                                                        + exception.getMessage(), bundle);
1134
                                }
1135
                        }
1136
                }
1137
        
1138
        public HttpBundle saveObject() throws CloudServersException{
1139
                Map<String,String> headers = new HashMap<String,String>();
1140
                if(objects.getMetadata()!=null)
1141
                        for(Entry<String,String> entry : objects.getMetadata().entrySet()){
1142
                                headers.put("X-Object-Meta-"+entry.getKey(), entry.getValue());
1143
                        }
1144
                for(String s : metadataRemoved){
1145
                        headers.put("X-Object-Meta-"+s, "~");
1146
                }
1147
                if(!isFolder())
1148
                        headers.put("X-Object-Public", String.valueOf(objects.isPublicf()));
1149
                String read ="";
1150
                String write="";
1151
                for(Permission p : objects.getPermissions()){
1152
                        if(p.isWrite()){
1153
                                if(!write.equals("")){
1154
                                        write = write+",";
1155
                                }
1156
                                write = write + (p.getGroup()==null?p.getUser():p.getGroup());
1157
                        }
1158
                        else if(p.isRead()){
1159
                                if(!read.equals("")){
1160
                                        read = read+",";
1161
                                }
1162
                                read = read + (p.getGroup()==null?p.getUser():p.getGroup());
1163
                        }
1164
                        
1165
                        
1166
                }
1167
                Log.d(LOG,"read:"+read);
1168
                Log.d(LOG,"write:"+write);
1169
                if(!"".equals(read)&&!"".equals(write)){
1170
                        read = "read="+read;
1171
                        write = "write="+write;
1172
                        headers.put("X-Object-Sharing", read+";"+write);
1173
                }
1174
                HttpBundle b = new ContainerObjectManager(getApplicationContext()).updateObject(objects.getContainerName(), objects.getCName(), "", null, headers);
1175
                Log.i(LOG,"response:"+b.getResponse().getStatusLine().getStatusCode());
1176
                return b;
1177
        }
1178
        
1179
        public HttpBundle restoreVersion(String version) throws CloudServersException{
1180
                Log.i(LOG,"Update version:"+version);
1181
                Map<String,String> headers=new HashMap<String, String>();
1182
                
1183
                headers.put("X-Source-Object","/"+objects.getContainerName()+"/"+objects.getCName());
1184
                headers.put("X-Source-Version",version);
1185
                headers.put("Content-Range","bytes 0-/*");
1186
                HttpBundle b = new ContainerObjectManager(getApplicationContext()).updateObject(objects.getContainerName(), objects.getCName(), "", "text/plain; charset=UTF-8", headers);
1187
                Log.i(LOG,"response:"+b.getResponse().getStatusLine().getStatusCode());
1188
                return b;
1189
        }
1190
        
1191

    
1192
}