Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / ContainerObjectDetails.java @ 1637229b

History | View | Annotate | Download (36.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 otherUser;
72
        private String cdnURL;
73
        private String cdnEnabled;
74
        public String LOG = "ViewObject";
75
        private int bConver = 1048576;
76
        private int kbConver = 1024;
77
        private double megaBytes;
78
        private double kiloBytes;
79
        public Button previewButton;
80
        public Button downloadButton;
81
        private Boolean isDownloaded;
82
        private AndroidCloudApplication app;
83
        private DeleteObjectListenerTask deleteObjTask;
84
        private DownloadObjectListenerTask downloadObjTask;
85
        private List<ObjectVersion> versions = new ArrayList<ObjectVersion>();
86
        private boolean isReadOnly = false;
87
        private final List<String> metadataRemoved = new ArrayList<String>();
88
        private final Map<String, String> metadataAdded = new HashMap<String, String>();
89

    
90
        /** Called when the activity is first created. */
91
        @Override
92
        public void onCreate(Bundle savedInstanceState) {
93
                super.onCreate(savedInstanceState);
94
                trackPageView(GoogleAnalytics.PAGE_STORAGE_OBJECT);
95

    
96
                objects = (ContainerObjects) this.getIntent().getExtras()
97
                                .get("container");
98
                otherUser = (String) this.getIntent().getExtras().get("otherUser");
99
                Log.i(LOG, "OTHERUSER:" + otherUser);
100
                containerNames = (String) this.getIntent().getExtras()
101
                                .get("containerNames");
102
                cdnURL = (String) this.getIntent().getExtras().get("cdnUrl");
103
                cdnEnabled = (String) this.getIntent().getExtras().get("isCdnEnabled");
104

    
105
                setContentView(R.layout.viewobject);
106
                TabHost tabs = (TabHost) findViewById(R.id.tabhost2);
107

    
108
                tabs.setup();
109

    
110
                TabHost.TabSpec spec = tabs.newTabSpec("tag1");
111

    
112
                spec.setContent(R.id.details);
113
                spec.setIndicator("Details");
114
                tabs.addTab(spec);
115

    
116
                spec = tabs.newTabSpec("tag2");
117
                spec.setContent(R.id.metadata);
118
                spec.setIndicator("Metadata");
119
                tabs.addTab(spec);
120

    
121
                spec = tabs.newTabSpec("tag3");
122
                spec.setContent(R.id.sharing);
123
                spec.setIndicator("Sharing");
124
                tabs.addTab(spec);
125

    
126
                spec = tabs.newTabSpec("tag4");
127
                spec.setContent(R.id.versions);
128
                spec.setIndicator("Versions");
129
                tabs.addTab(spec);
130

    
131
                restoreState(savedInstanceState);
132
        }
133

    
134
        public boolean isFolder() {
135
                return objects.getContentType().startsWith("application/folder")
136
                                || objects.getContentType().startsWith("application/directory");
137
        }
138

    
139
        @Override
140
        protected void onSaveInstanceState(Bundle outState) {
141
                super.onSaveInstanceState(outState);
142
                outState.putSerializable("container", objects);
143
                outState.putBoolean("isDownloaded", isDownloaded);
144
        }
145

    
146
        protected void restoreState(Bundle state) {
147
                super.restoreState(state);
148
                /*
149
                 * need reference to the app so you can access curDirFiles as well as
150
                 * processing status
151
                 */
152
                app = (AndroidCloudApplication) this.getApplication();
153

    
154
                if (state != null && state.containsKey("container")) {
155
                        objects = (ContainerObjects) state.getSerializable("container");
156
                }
157
                if (containerNames.equals(Container.MYSHARED)
158
                                || containerNames.equals(Container.OTHERS))
159
                        loadObjectData();
160
                else
161
                        new ContainerObjectRefreshTask().execute();
162

    
163
                if (cdnEnabled.equals("true")) {
164
                        this.previewButton = (Button) findViewById(R.id.preview_button);
165
                        previewButton.setOnClickListener(new MyOnClickListener());
166
                } else {
167
                        this.previewButton = (Button) findViewById(R.id.preview_button);
168
                        previewButton.setVisibility(View.GONE);
169
                }
170

    
171
                if (state != null && state.containsKey("isDownloaded")) {
172
                        isDownloaded = state.getBoolean("isDownloaded");
173
                } else {
174
                        isDownloaded = fileIsDownloaded();
175
                }
176
                this.downloadButton = (Button) findViewById(R.id.download_button);
177
                if (isDownloaded) {
178
                        downloadButton.setText("Open File");
179
                } else {
180
                        downloadButton.setText("Download File");
181
                }
182
                downloadButton.setOnClickListener(new MyOnClickListener());
183

    
184
                if (app.isDeletingObject()) {
185
                        deleteObjTask = new DeleteObjectListenerTask();
186
                        deleteObjTask.execute();
187
                }
188

    
189
                if (app.isDownloadingObject()) {
190
                        downloadObjTask = new DownloadObjectListenerTask();
191
                        downloadObjTask.execute();
192
                }
193

    
194
        }
195

    
196
        @Override
197
        protected void onStop() {
198
                super.onStop();
199

    
200
                /*
201
                 * Need to stop running listener task if we exit
202
                 */
203
                if (deleteObjTask != null) {
204
                        deleteObjTask.cancel(true);
205
                }
206

    
207
                if (downloadObjTask != null) {
208
                        downloadObjTask.cancel(true);
209
                }
210
        }
211

    
212
        private void loadObjectData() {
213
                setTitle("Details: " + objects.getCName());
214
                metadataRemoved.clear();
215
                metadataAdded.clear();
216
                if (Container.MYSHARED.equals(objects.getContainerName())
217
                                || Container.MYSHARED.equals(containerNames)) {
218
                        isReadOnly = true;
219

    
220
                }
221
                // Object Name
222
                TextView name = (TextView) findViewById(R.id.view_container_name);
223
                name.setText(objects.getCName().toString());
224

    
225
                // File size
226
                if (objects.getBytes() >= bConver) {
227
                        megaBytes = Math.abs(objects.getBytes() / bConver + 0.2);
228
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
229
                        sublabel.setText(megaBytes + " MB");
230
                } else if (objects.getBytes() >= kbConver) {
231
                        kiloBytes = Math.abs(objects.getBytes() / kbConver + 0.2);
232
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
233
                        sublabel.setText(kiloBytes + " KB");
234
                } else {
235
                        TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
236
                        sublabel.setText(objects.getBytes() + " B");
237
                }
238

    
239
                // Content Type
240
                TextView cType = (TextView) findViewById(R.id.view_content_type);
241
                if (objects.getContentType() != null)
242
                        cType.setText(objects.getContentType().toString());
243
                else
244
                        cType.setText("");
245

    
246
                // Last Modification date
247
                String strDate = objects.getLastMod();
248
                strDate = strDate.substring(0, strDate.indexOf('T'));
249

    
250
                TextView lastmod = (TextView) findViewById(R.id.view_file_modification);
251
                lastmod.setText(strDate);
252
                rebuildMetadataList();
253
                if (isFolder()) {
254
                        findViewById(R.id.download_text).setVisibility(View.GONE);
255
                        findViewById(R.id.linearLayout1).setVisibility(View.GONE);
256
                        findViewById(R.id.layoutPublic).setVisibility(View.GONE);
257
                }
258
                rebuildPermissionList();
259
                try {
260
                        new AsyncTask<Void, Void, List<ObjectVersion>>() {
261

    
262
                                @Override
263
                                protected List<ObjectVersion> doInBackground(Void... params) {
264
                                        try {
265
                                                return new ContainerObjectManager(
266
                                                                getApplicationContext()).getObjectVersions(
267
                                                                objects.getContainerName(), objects.getCName(),
268
                                                                otherUser);
269
                                        } catch (CloudServersException e) {
270
                                                Log.e("ERROR", "", e);
271
                                                return null;
272
                                        }
273

    
274
                                }
275

    
276
                                @Override
277
                                protected void onPostExecute(List<ObjectVersion> result) {
278
                                        if (result != null) {
279
                                                versions = result;
280
                                                rebuildVersionList();
281
                                        }
282
                                }
283

    
284
                        };
285
                } catch (Exception e) {
286
                        Log.e("ERROR THERE", "", e);
287
                }
288

    
289
        }
290

    
291
        private void rebuildMetadataList() {
292
                Button newmetadata = (Button) findViewById(R.id.newMetadata);
293
                if (isReadOnly)
294
                        newmetadata.setVisibility(View.GONE);
295
                newmetadata.setOnClickListener(new OnClickListener() {
296

    
297
                        @Override
298
                        public void onClick(View arg0) {
299
                                final AlertDialog.Builder alert = new AlertDialog.Builder(
300
                                                ContainerObjectDetails.this);
301
                                alert.setTitle("Add Metadata");
302
                                LinearLayout ll = new LinearLayout(ContainerObjectDetails.this);
303
                                ll.setOrientation(LinearLayout.VERTICAL);
304

    
305
                                final EditText input = new EditText(ContainerObjectDetails.this);
306
                                final EditText input2 = new EditText(
307
                                                ContainerObjectDetails.this);
308
                                ll.addView(input);
309
                                ll.addView(input2);
310
                                alert.setView(ll);
311
                                alert.setPositiveButton("Create",
312
                                                new DialogInterface.OnClickListener() {
313
                                                        public void onClick(DialogInterface dialog,
314
                                                                        int whichButton) {
315
                                                                String key = input.getText().toString().trim();
316
                                                                String value = input2.getText().toString()
317
                                                                                .trim();
318
                                                                addMetatadata(key, value);
319
                                                        }
320
                                                });
321

    
322
                                alert.setNegativeButton("Cancel",
323
                                                new DialogInterface.OnClickListener() {
324
                                                        public void onClick(DialogInterface dialog,
325
                                                                        int whichButton) {
326
                                                                dialog.cancel();
327
                                                        }
328
                                                });
329
                                alert.show();
330
                        }
331
                });
332
                LayoutInflater layoutInflater = LayoutInflater
333
                                .from(ContainerObjectDetails.this);
334
                final LinearLayout metadata = (LinearLayout) findViewById(R.id.metadataList);
335
                if (metadata.getChildCount() > 0)
336
                        metadata.removeViews(0, metadata.getChildCount());
337
                metadata.removeAllViews();
338

    
339
                if (objects.getMetadata() != null) {
340
                        int i = 0;
341
                        Iterator<Entry<String, String>> it = objects.getMetadata()
342
                                        .entrySet().iterator();
343
                        while (it.hasNext()) {
344
                                final Entry<String, String> perm = it.next();
345
                                final View v = layoutInflater.inflate(R.layout.metadatarow,
346
                                                null);
347
                                populateMetadataList(perm, v, metadata, i);
348
                                i++;
349
                        }
350
                }
351
        }
352

    
353
        private void addMetatadata(String key, String value) {
354
                if (objects.getMetadata() == null)
355
                        objects.setMetadata(new HashMap<String, String>());
356
                metadataAdded.put(key, value);
357
                objects.getMetadata().put(key, value);
358
                rebuildMetadataList();
359
        }
360

    
361
        private void populateMetadataList(final Entry<String, String> metadata,
362
                        final View v, final LinearLayout properties, int i) {
363
                properties.addView(v, i);
364
                Log.d(LOG, i + " " + metadata.getKey() + " " + metadata.getValue());
365
                ((TextView) v.findViewById(R.id.mkey)).setText(metadata.getKey());
366
                ((TextView) v.findViewById(R.id.mvalue)).setText(metadata.getValue());
367
                if (isReadOnly)
368
                        v.findViewById(R.id.remove).setVisibility(View.GONE);
369
                ((ImageButton) v.findViewById(R.id.remove))
370
                                .setOnClickListener(new OnClickListener() {
371

    
372
                                        @Override
373
                                        public void onClick(View v1) {
374
                                                properties.removeView(v);
375
                                                metadataRemoved.add(metadata.getKey());
376
                                                objects.getMetadata().remove(metadata.getKey());
377

    
378
                                        }
379
                                });
380
        }
381

    
382
        private void rebuildPermissionList() {
383
                Button newmetadata = (Button) findViewById(R.id.newPermission);
384
                CheckBox readForAll = (CheckBox) findViewById(R.id.folderPublic);
385
                if (isReadOnly) {
386
                        newmetadata.setVisibility(View.GONE);
387
                        readForAll.setEnabled(false);
388
                }
389
                objects.setPublicf(objects.getIsPublic() != null);
390
                readForAll.setChecked(objects.isPublicf());
391

    
392
                readForAll.setOnCheckedChangeListener(new OnCheckedChangeListener() {
393

    
394
                        @Override
395
                        public void onCheckedChanged(CompoundButton buttonView,
396
                                        boolean isChecked) {
397
                                objects.setPublicf(isChecked);
398

    
399
                        }
400
                });
401
                newmetadata.setOnClickListener(new OnClickListener() {
402

    
403
                        @Override
404
                        public void onClick(View v) {
405
                                showAddDialog();
406
                        }
407

    
408
                });
409
                LayoutInflater layoutInflater = LayoutInflater
410
                                .from(ContainerObjectDetails.this);
411
                final LinearLayout properties = (LinearLayout) findViewById(R.id.permissionsList);
412
                if (properties.getChildCount() > 0)
413
                        properties.removeViews(0, properties.getChildCount());
414
                properties.removeAllViews();
415
                Iterator<Permission> it = null;
416
                if (objects.getPermissions() != null) {
417
                        it = objects.getPermissions().iterator();
418
                        int i = 0;
419
                        while (it.hasNext()) {
420
                                final Permission perm = it.next();
421
                                final View v = layoutInflater.inflate(R.layout.propertiesrow,
422
                                                null);
423
                                populatePermissionList(perm, v, properties, i);
424
                                i++;
425
                        }
426
                }
427
        }
428

    
429
        private void populatePermissionList(final Permission perm, final View v,
430
                        final LinearLayout properties, int i) {
431

    
432
                properties.addView(v, i);
433
                if (isReadOnly) {
434
                        v.findViewById(R.id.remove).setVisibility(View.GONE);
435
                        ((CheckBox) v.findViewById(R.id.read)).setEnabled(false);
436
                        ((CheckBox) v.findViewById(R.id.write)).setEnabled(false);
437
                }
438

    
439
                ((TextView) v.findViewById(R.id.ownerName))
440
                                .setText(perm.getUser() == null ? perm.getGroup() + ":" : perm
441
                                                .getUser());
442
                ((CheckBox) v.findViewById(R.id.read)).setChecked(perm.isRead());
443
                ((CheckBox) v.findViewById(R.id.write)).setChecked(perm.isWrite());
444

    
445
                ((CheckBox) v.findViewById(R.id.read))
446
                                .setOnCheckedChangeListener(new OnCheckedChangeListener() {
447

    
448
                                        @Override
449
                                        public void onCheckedChanged(CompoundButton buttonView,
450
                                                        boolean isChecked) {
451
                                                perm.setRead(isChecked);
452

    
453
                                        }
454
                                });
455
                ((CheckBox) v.findViewById(R.id.write))
456
                                .setOnCheckedChangeListener(new OnCheckedChangeListener() {
457

    
458
                                        @Override
459
                                        public void onCheckedChanged(CompoundButton buttonView,
460
                                                        boolean isChecked) {
461
                                                perm.setWrite(isChecked);
462

    
463
                                        }
464
                                });
465
                ((Button) v.findViewById(R.id.remove))
466
                                .setOnClickListener(new OnClickListener() {
467

    
468
                                        @Override
469
                                        public void onClick(View v1) {
470
                                                properties.removeView(v);
471
                                                objects.getPermissions().remove(perm);
472

    
473
                                        }
474
                                });
475
        }
476

    
477
        private void addPermission(boolean group, String userOrGroup) {
478
                if (objects.getPermissions() == null)
479
                        objects.setPermissions(new ArrayList<Permission>());
480
                Permission np = new Permission();
481
                if (group)
482
                        np.setGroup(userOrGroup);
483
                else
484
                        np.setUser(userOrGroup);
485
                objects.getPermissions().add(np);
486
                rebuildPermissionList();
487
        }
488

    
489
        private void showAddDialog() {
490
                final CharSequence[] items = { "Add User", "Add Group" };
491

    
492
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
493
                builder.setTitle("User Or Group");
494
                builder.setSingleChoiceItems(items, -1,
495
                                new DialogInterface.OnClickListener() {
496
                                        public void onClick(DialogInterface dialog, int item) {
497
                                                boolean user;
498
                                                if (item == 0) {
499
                                                        user = true;
500
                                                } else
501
                                                        user = false;
502
                                                populateAddDialog(user);
503
                                                dialog.dismiss();
504

    
505
                                        }
506
                                });
507
                AlertDialog alert2 = builder.create();
508
                alert2.show();
509

    
510
        }
511

    
512
        private void populateAddDialog(final boolean user) {
513
                final AlertDialog.Builder alert = new AlertDialog.Builder(
514
                                ContainerObjectDetails.this);
515
                if (user) {
516
                        alert.setTitle("Add User");
517
                        final EditText input = new EditText(ContainerObjectDetails.this);
518
                        input.setTextColor(Color.BLACK);
519

    
520
                        alert.setView(input);
521

    
522
                        alert.setPositiveButton("Add",
523
                                        new DialogInterface.OnClickListener() {
524
                                                public void onClick(DialogInterface dialog,
525
                                                                int whichButton) {
526
                                                        String value = input.getText().toString().trim();
527
                                                        addPermission(false, value);
528

    
529
                                                }
530
                                        });
531

    
532
                        alert.setNegativeButton("Cancel",
533
                                        new DialogInterface.OnClickListener() {
534
                                                public void onClick(DialogInterface dialog,
535
                                                                int whichButton) {
536
                                                        dialog.cancel();
537

    
538
                                                }
539
                                        });
540
                        alert.show();
541
                } else {
542
                        AlertDialog.Builder builder = new AlertDialog.Builder(this);
543
                        builder.setTitle("Add Group");
544
                        builder.setSingleChoiceItems(
545
                                        getGroupNames().toArray(new String[0]), -1,
546
                                        new DialogInterface.OnClickListener() {
547
                                                public void onClick(DialogInterface dialog, int item) {
548
                                                        addPermission(true, getGroupNames().get(item));
549
                                                        dialog.dismiss();
550

    
551
                                                }
552
                                        });
553
                        AlertDialog alert2 = builder.create();
554
                        alert2.show();
555
                }
556

    
557
        }
558

    
559
        public List<String> getGroupNames() {
560
                List<String> result = new ArrayList<String>();
561
                List<GroupResource> groups = ((AndroidCloudApplication) getApplication())
562
                                .getGroups();
563
                for (GroupResource g : groups) {
564
                        result.add(g.getName());
565
                }
566
                return result;
567
        }
568

    
569
        private void rebuildVersionList() {
570
                LayoutInflater layoutInflater = LayoutInflater
571
                                .from(ContainerObjectDetails.this);
572
                final LinearLayout properties = (LinearLayout) findViewById(R.id.versionsList);
573
                if (properties.getChildCount() > 0)
574
                        properties.removeViews(0, properties.getChildCount());
575
                properties.removeAllViews();
576
                Iterator<ObjectVersion> it;
577
                // Collections.reverse(versions);
578
                it = versions.iterator();
579
                int i = 0;
580
                while (it.hasNext()) {
581
                        final ObjectVersion perm = it.next();
582
                        final View v = layoutInflater.inflate(R.layout.versionsrow, null);
583
                        populateVersionList(perm, v, properties, i);
584
                        i++;
585
                }
586
        }
587

    
588
        String selectedVersion = null;
589

    
590
        private void populateVersionList(final ObjectVersion perm, final View v,
591
                        final LinearLayout properties, int i) {
592

    
593
                properties.addView(v, i);
594

    
595
                ((TextView) v.findViewById(R.id.versionName)).setText("Version: "
596
                                + perm.getVersion());
597

    
598
                ((TextView) v.findViewById(R.id.versionModified)).setText("Modified: "
599
                                + perm.getDateString());
600
                if (versions.size() == 1 || isReadOnly) {
601
                        // ((Button)
602
                        // v.findViewById(R.id.vremove)).setVisibility(View.INVISIBLE);
603
                        ((Button) v.findViewById(R.id.vrestore))
604
                                        .setVisibility(View.INVISIBLE);
605
                }
606
                /*
607
                 * ((Button) v.findViewById(R.id.vremove)) .setOnClickListener(new
608
                 * OnClickListener() {
609
                 * 
610
                 * @Override public void onClick(View v1) { Log.d("PERMS",
611
                 * perm.getUri()); try { new GssHttpCommands(getDroidApplication()
612
                 * .getUserDetails
613
                 * ()).deleteFolder(perm.getUri()+"?version="+perm.getVersion()); }
614
                 * catch (SystemErrorException e) { // TODO Auto-generated catch block
615
                 * e.printStackTrace(); } catch (GssHttpException e) { // TODO
616
                 * Auto-generated catch block e.printStackTrace(); }
617
                 * getFileTask().execute(res.getUri()); //properties.removeView(v);
618
                 * 
619
                 * } });
620
                 */
621
                ((Button) v.findViewById(R.id.vrestore))
622
                                .setOnClickListener(new OnClickListener() {
623

    
624
                                        @Override
625
                                        public void onClick(View v1) {
626
                                                selectedVersion = String.valueOf(perm.getVersion());
627
                                                showDialog(restoreVersion);
628

    
629
                                        }
630
                                });
631
                ((Button) v.findViewById(R.id.vdownload))
632
                                .setOnClickListener(new OnClickListener() {
633

    
634
                                        @Override
635
                                        public void onClick(View v1) {
636
                                                if (storageIsReady()) {
637
                                                        new ContainerObjectDownloadTask().execute(String
638
                                                                        .valueOf(perm.getVersion()));
639
                                                } else {
640
                                                        showAlert("Error", "Storage not found.");
641
                                                }
642
                                                // getDownloadTask().execute(perm.getUri()+"?version="+perm.getVersion());
643
                                                // properties.removeView(v);
644

    
645
                                        }
646
                                });
647
        }
648

    
649
        private class MyOnClickListener implements View.OnClickListener {
650
                @Override
651
                public void onClick(View v) {
652
                        if (v.equals(findViewById(R.id.preview_button))) {
653
                                Intent viewIntent = new Intent("android.intent.action.VIEW",
654
                                                Uri.parse(cdnURL + "/" + objects.getCName()));
655
                                startActivity(viewIntent);
656
                        }
657
                        /*
658
                         * need to perform different functions based on if the file is in
659
                         * the devices filesystem
660
                         */
661
                        if (v.equals(findViewById(R.id.download_button))) {
662
                                if (!isDownloaded) {
663
                                        if (storageIsReady()) {
664
                                                new ContainerObjectDownloadTask().execute();
665
                                        } else {
666
                                                showAlert("Error", "Storage not found.");
667
                                        }
668
                                } else {
669
                                        openFile();
670
                                }
671
                        }
672
                }
673
        }
674

    
675
        // Create the Menu options
676
        @Override
677
        public boolean onCreateOptionsMenu(Menu menu) {
678
                super.onCreateOptionsMenu(menu);
679
                MenuInflater inflater = getMenuInflater();
680
                inflater.inflate(R.menu.container_object_list_menu, menu);
681
                menu.findItem(R.id.delete_object).setVisible(!isReadOnly);
682
                menu.findItem(R.id.save).setVisible(!isReadOnly);
683
                return true;
684
        }
685

    
686
        @Override
687
        public boolean onOptionsItemSelected(MenuItem item) {
688
                switch (item.getItemId()) {
689
                case R.id.delete_object:
690
                        showDialog(deleteObject);
691
                        return true;
692
                case R.id.refresh:
693
                        if (containerNames.equals(Container.MYSHARED)
694
                                        || containerNames.equals(Container.OTHERS))
695
                                loadObjectData();
696
                        else
697
                                new ContainerObjectRefreshTask().execute();
698

    
699
                        return true;
700
                case R.id.save:
701
                        new ContainerObjectUpdateTask().execute();
702
                        return true;
703
                }
704
                return false;
705
        }
706

    
707
        @Override
708
        protected Dialog onCreateDialog(int id) {
709
                switch (id) {
710
                case deleteObject:
711
                        return new AlertDialog.Builder(ContainerObjectDetails.this)
712
                                        .setIcon(R.drawable.alert_dialog_icon)
713
                                        .setTitle("Delete File")
714
                                        .setMessage("Are you sure you want to delete this file?")
715
                                        .setPositiveButton("Delete File",
716
                                                        new DialogInterface.OnClickListener() {
717
                                                                public void onClick(DialogInterface dialog,
718
                                                                                int whichButton) {
719
                                                                        // User clicked OK so do some stuff
720
                                                                        trackEvent(GoogleAnalytics.CATEGORY_FILE,
721
                                                                                        GoogleAnalytics.EVENT_DELETE, "",
722
                                                                                        -1);
723
                                                                        new ContainerObjectDeleteTask()
724
                                                                                        .execute((Void[]) null);
725
                                                                }
726
                                                        })
727
                                        .setNegativeButton("Cancel",
728
                                                        new DialogInterface.OnClickListener() {
729
                                                                public void onClick(DialogInterface dialog,
730
                                                                                int whichButton) {
731
                                                                        // User clicked Cancel so do some stuff
732
                                                                }
733
                                                        }).create();
734
                case restoreVersion:
735
                        return new AlertDialog.Builder(ContainerObjectDetails.this)
736
                                        .setIcon(R.drawable.alert_dialog_icon)
737
                                        .setTitle("Restore Version")
738
                                        .setMessage(
739
                                                        "Are you sure you want to restore this version?")
740
                                        .setPositiveButton("Restore Version",
741
                                                        new DialogInterface.OnClickListener() {
742
                                                                public void onClick(DialogInterface dialog,
743
                                                                                int whichButton) {
744
                                                                        // User clicked OK so do some stuff
745
                                                                        /*
746
                                                                         * trackEvent(GoogleAnalytics.CATEGORY_FILE,
747
                                                                         * GoogleAnalytics.EVENT_DELETE, "", -1);
748
                                                                         */
749
                                                                        new VersionRestoreTask()
750
                                                                                        .execute(selectedVersion);
751
                                                                }
752
                                                        })
753
                                        .setNegativeButton("Cancel",
754
                                                        new DialogInterface.OnClickListener() {
755
                                                                public void onClick(DialogInterface dialog,
756
                                                                                int whichButton) {
757
                                                                        // User clicked Cancel so do some stuff
758
                                                                }
759
                                                        }).create();
760

    
761
                }
762

    
763
                return null;
764
        }
765

    
766
        /**
767
         * @return the file
768
         */
769
        public ContainerObjects getViewFile() {
770
                return objects;
771
        }
772

    
773
        /**
774
         * @param File
775
         *            the file to set
776
         */
777
        public void setViewFile(ContainerObjects object) {
778
                this.objects = object;
779
        }
780

    
781
        /*
782
         * returns false if external storage is not avaliable (if its mounted,
783
         * missing, read-only, etc) from:
784
         * http://developer.android.com/guide/topics/data
785
         * /data-storage.html#filesExternal
786
         */
787
        private boolean storageIsReady() {
788
                boolean mExternalStorageAvailable = false;
789
                boolean mExternalStorageWriteable = false;
790
                String state = Environment.getExternalStorageState();
791

    
792
                if (Environment.MEDIA_MOUNTED.equals(state)) {
793
                        // We can read and write the media
794
                        mExternalStorageAvailable = mExternalStorageWriteable = true;
795
                } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
796
                        // We can only read the media
797
                        mExternalStorageAvailable = true;
798
                        mExternalStorageWriteable = false;
799
                } else {
800
                        // Something else is wrong. It may be one of many other states, but
801
                        // all we need
802
                        // to know is we can neither read nor write
803
                        mExternalStorageAvailable = mExternalStorageWriteable = false;
804
                }
805
                return mExternalStorageAvailable && mExternalStorageWriteable;
806
        }
807

    
808
        private boolean fileIsDownloaded() {
809
                if (storageIsReady()) {
810
                        String fileName = Environment.getExternalStorageDirectory()
811
                                        .getPath() + "/PithosPlus/" + objects.getCName();
812
                        File f = new File(fileName);
813
                        return f.isFile();
814
                }
815
                return false;
816
        }
817

    
818
        private void openFile() {
819
                File object = new File(Environment.getExternalStorageDirectory()
820
                                .getPath() + "/PithosPlus/" + objects.getCName());
821
                Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
822
                File file = new File(object.getAbsolutePath());
823
                String extension = android.webkit.MimeTypeMap
824
                                .getFileExtensionFromUrl(Uri.fromFile(file).toString());
825
                String mimetype = android.webkit.MimeTypeMap.getSingleton()
826
                                .getMimeTypeFromExtension(extension);
827
                myIntent.setDataAndType(Uri.fromFile(file), mimetype);
828
                // myIntent.setData(Uri.fromFile(file));
829
                try {
830
                        startActivity(myIntent);
831
                } catch (Exception e) {
832
                        Toast.makeText(this, "Could not open file.", Toast.LENGTH_SHORT)
833
                                        .show();
834
                }
835
        }
836

    
837
        // Task's
838

    
839
        private class ContainerObjectRefreshTask extends
840
                        AsyncTask<Void, Void, ContainerObjects> {
841

    
842
                private CloudServersException exception;
843

    
844
                protected void onPreExecute() {
845
                        showDialog();
846
                }
847

    
848
                @Override
849
                protected ContainerObjects doInBackground(Void... arg0) {
850
                        ContainerObjects bundle = null;
851
                        try {
852
                                if (otherUser == null)
853
                                        bundle = (new ContainerObjectManager(getContext()))
854
                                                        .executeHead(containerNames, objects.getCName());
855
                                else
856
                                        bundle = (new ContainerObjectManager(getContext()))
857
                                                        .executeHead(containerNames, objects.getCName(),
858
                                                                        otherUser);
859
                        } catch (CloudServersException e) {
860
                                exception = e;
861
                        }
862

    
863
                        return bundle;
864
                }
865

    
866
                @Override
867
                protected void onPostExecute(ContainerObjects bundle) {
868
                        hideDialog();
869
                        if (bundle != null) {
870
                                objects = bundle;
871
                                loadObjectData();
872
                        } else if (exception != null) {
873
                                showToast("There was a problem refreshing your file: "
874
                                                + exception.getMessage());
875
                        }
876
                }
877
        }
878

    
879
        private class ContainerObjectDeleteTask extends
880
                        AsyncTask<Void, Void, HttpBundle> {
881

    
882
                private CloudServersException exception;
883

    
884
                protected void onPreExecute() {
885
                        showDialog();
886
                        app.setDeleteingObject(true);
887
                        deleteObjTask = new DeleteObjectListenerTask();
888
                        deleteObjTask.execute();
889
                }
890

    
891
                @Override
892
                protected HttpBundle doInBackground(Void... arg0) {
893
                        HttpBundle bundle = null;
894
                        try {
895
                                bundle = (new ContainerObjectManager(getContext()))
896
                                                .deleteObject(containerNames, objects.getCName(),
897
                                                                otherUser);
898
                        } catch (CloudServersException e) {
899
                                exception = e;
900
                        }
901

    
902
                        return bundle;
903
                }
904

    
905
                @Override
906
                protected void onPostExecute(HttpBundle bundle) {
907
                        app.setDeleteingObject(false);
908
                        hideDialog();
909
                        HttpResponse response = bundle.getResponse();
910
                        if (response != null) {
911
                                int statusCode = response.getStatusLine().getStatusCode();
912
                                if (statusCode == 204) {
913
                                        // handled by listener
914
                                } else {
915
                                        CloudServersException cse = parseCloudServersException(response);
916
                                        if ("".equals(cse.getMessage())) {
917
                                                showError("There was a problem deleting your File.",
918
                                                                bundle);
919
                                        } else {
920
                                                showError("There was a problem deleting your file: "
921
                                                                + cse.getMessage(), bundle);
922
                                        }
923
                                }
924
                        } else if (exception != null) {
925
                                showError("There was a problem deleting your file: "
926
                                                + exception.getMessage(), bundle);
927
                        }
928
                }
929
        }
930

    
931
        private class ContainerObjectDownloadTask extends
932
                        AsyncTask<String, Void, HttpBundle> {
933

    
934
                private CloudServersException exception;
935

    
936
                @Override
937
                protected void onPreExecute() {
938
                        showDialog();
939
                        app.setDownloadingObject(true);
940
                        
941
                }
942

    
943
                @Override
944
                protected HttpBundle doInBackground(String... arg0) {
945
                        HttpBundle bundle = null;
946
                        try {
947
                                if (arg0.length == 1 && arg0[0] != null)
948
                                        bundle = (new ContainerObjectManager(getContext()))
949
                                                        .getObject(containerNames, objects.getCName(),
950
                                                                        arg0[0], otherUser);
951
                                else
952
                                        bundle = (new ContainerObjectManager(getContext()))
953
                                                        .getObject(containerNames, objects.getCName(),
954
                                                                        otherUser);
955
                        } catch (CloudServersException e) {
956
                                e.printStackTrace();
957
                                exception = e;
958
                        } catch (Exception exx) {
959
                                exx.printStackTrace();
960
                        }
961
                        return bundle;
962
                }
963

    
964
                @Override
965
                protected void onPostExecute(HttpBundle bundle) {
966
                        hideDialog();
967
                        HttpResponse response = bundle.getResponse();
968
                        if (response != null) {
969
                                int statusCode = response.getStatusLine().getStatusCode();
970
                                if (statusCode == 200) {
971
                                        setResult(Activity.RESULT_OK);
972
                                        HttpEntity entity = response.getEntity();
973
                                        app.setDownloadedEntity(entity);
974
                                        downloadObjTask = new DownloadObjectListenerTask();
975
                                        downloadObjTask.execute();
976
                                } else {
977
                                        CloudServersException cse = parseCloudServersException(response);
978
                                        if ("".equals(cse.getMessage())) {
979
                                                showError("There was a problem downloading your File.",
980
                                                                bundle);
981
                                        } else {
982
                                                showError("There was a problem downloading your file: "
983
                                                                + cse.getMessage(), bundle);
984
                                        }
985
                                }
986
                        } else if (exception != null) {
987
                                showError("There was a problem downloading your file: "
988
                                                + exception.getMessage(), bundle);
989
                        }
990
                        app.setDownloadingObject(false);
991
                }
992
        }
993

    
994
        private class DeleteObjectListenerTask extends AsyncTask<Void, Void, Void> {
995

    
996
                @Override
997
                protected Void doInBackground(Void... arg1) {
998

    
999
                        while (app.isDeletingObject()) {
1000
                                // wait for process to finish
1001
                                // or have it be canceled
1002
                                if (deleteObjTask.isCancelled()) {
1003
                                        return null;
1004
                                }
1005
                        }
1006
                        return null;
1007
                }
1008

    
1009
                /*
1010
                 * when no longer processing, time to load the new files
1011
                 */
1012
                @Override
1013
                protected void onPostExecute(Void arg1) {
1014
                        hideDialog();
1015
                        setResult(99);
1016
                        finish();
1017
                }
1018
        }
1019

    
1020
        private class DownloadObjectListenerTask extends
1021
                        AsyncTask<Void, Void, Void> {
1022

    
1023
                @Override
1024
                protected Void doInBackground(Void... arg1) {
1025

    
1026
                        while (app.isDownloadingObject()) {
1027
                                // wait for process to finish
1028
                                // or have it be canceled
1029
                                if (downloadObjTask.isCancelled()) {
1030
                                        return null;
1031
                                }
1032
                        }
1033
                        return null;
1034
                }
1035

    
1036
                /*
1037
                 * when no longer processing, time to load the new files
1038
                 */
1039
                @Override
1040
                protected void onPostExecute(Void arg1) {
1041
                        try {
1042
                                new WriteFileTask().execute(app.getDownloadedEntity()
1043
                                                .getContent());
1044
                        } catch (IllegalStateException e) {
1045
                                showAlert("Error", "There was a problem downloading your file.");
1046
                                e.printStackTrace();
1047
                        } catch (IOException e) {
1048
                                showAlert("Error", "There was a problem downloading your file.");
1049
                                e.printStackTrace();
1050
                        }
1051
                        hideDialog();
1052
                }
1053
        }
1054

    
1055
        class WriteFileTask extends AsyncTask<InputStream, Void, Boolean> {
1056
                @Override
1057
                protected void onPreExecute() {
1058
                        showDialog();
1059
                }
1060

    
1061
                @Override
1062
                protected Boolean doInBackground(InputStream... params) {
1063
                        return writeFile(params[0]);
1064
                }
1065

    
1066
                @Override
1067
                protected void onPostExecute(Boolean result) {
1068
                        hideDialog();
1069
                        if (result) {
1070
                                downloadButton.setText("Open File");
1071
                                isDownloaded = true;
1072
                        } else {
1073
                                showAlert("Error", "There was a problem downloading your file.");
1074
                        }
1075
                }
1076

    
1077
        }
1078

    
1079
        private boolean writeFile(InputStream in) {
1080
                String directoryName = Environment.getExternalStorageDirectory()
1081
                                .getPath();
1082
                File f = new File(directoryName, DOWNLOAD_DIRECTORY);
1083
                Log.i(LOG, directoryName);
1084
                if (!f.isDirectory()) {
1085
                        if (!f.mkdir()) {
1086
                                return false;
1087
                        }
1088
                }
1089
                Log.i(LOG, objects.toString());
1090
                // String filename = directoryName + "/" + objects.getName();
1091
                StringTokenizer str = new StringTokenizer(objects.getCName(), "/");
1092
                String path = "";
1093
                String fname = "";
1094
                int count = str.countTokens();
1095
                Log.i(LOG, "object is: " + objects.getCName() + " " + count);
1096
                for (int i = 0; i < count; i++) {
1097
                        if (i < (count - 1)) {
1098
                                path = path + str.nextToken() + "/";
1099
                        } else
1100
                                fname = str.nextToken();
1101
                }
1102
                Log.i(LOG, "Path is:" + path);
1103
                Log.i(LOG, "Fname is:" + fname);
1104
                File object;
1105
                if ("".equals(path)) {
1106
                        object = new File(f, fname);
1107
                } else {
1108
                        File t = new File(f, path);
1109
                        t.mkdirs();
1110
                        object = new File(t, fname);
1111
                }
1112

    
1113
                BufferedOutputStream bos = null;
1114

    
1115
                try {
1116
                        FileOutputStream fos = new FileOutputStream(object);
1117
                        copy(in, fos);
1118
                } catch (IOException e) {
1119
                        e.printStackTrace();
1120
                } finally {
1121
                        if (bos != null) {
1122
                                try {
1123
                                        bos.flush();
1124
                                        bos.close();
1125
                                } catch (IOException e) {
1126
                                        // TODO Auto-generated catch block
1127
                                        e.printStackTrace();
1128
                                }
1129
                        }
1130
                }
1131
                return true;
1132
        }
1133

    
1134
        public static long copy(InputStream input, OutputStream output)
1135
                        throws IOException {
1136

    
1137
                byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
1138
                long count = 0;
1139
                int n = 0;
1140
                try {
1141
                        while (-1 != (n = input.read(buffer))) {
1142
                                output.write(buffer, 0, n);
1143
                                count += n;
1144
                                // monitor.setCurrent(count);
1145
                        }
1146
                } finally {
1147
                        input.close();
1148
                        output.close();
1149
                }
1150
                return count;
1151
        }
1152

    
1153
        @Override
1154
        public void onBackPressed() {
1155

    
1156
                // TODO: perform update
1157
                super.onBackPressed();
1158
        }
1159

    
1160
        private class ContainerObjectUpdateTask extends
1161
                        AsyncTask<Void, Void, HttpBundle> {
1162

    
1163
                private CloudServersException exception;
1164

    
1165
                protected void onPreExecute() {
1166
                        showDialog();
1167
                }
1168

    
1169
                @Override
1170
                protected HttpBundle doInBackground(Void... arg0) {
1171
                        HttpBundle bundle = null;
1172
                        try {
1173
                                bundle = saveObject();
1174
                        } catch (CloudServersException e) {
1175
                                exception = e;
1176
                        }
1177

    
1178
                        return bundle;
1179
                }
1180

    
1181
                @Override
1182
                protected void onPostExecute(HttpBundle bundle) {
1183
                        hideDialog();
1184
                        HttpResponse response = bundle.getResponse();
1185
                        if (response != null) {
1186
                                int statusCode = response.getStatusLine().getStatusCode();
1187
                                if (statusCode == 202) {
1188
                                        hideDialog();
1189
                                        setResult(99);
1190
                                        finish();
1191
                                } else {
1192
                                        CloudServersException cse = parseCloudServersException(response);
1193
                                        if ("".equals(cse.getMessage())) {
1194
                                                showError("There was a problem deleting your File.",
1195
                                                                bundle);
1196
                                        } else {
1197
                                                showError("There was a problem deleting your file: "
1198
                                                                + cse.getMessage(), bundle);
1199
                                        }
1200
                                }
1201
                        } else if (exception != null) {
1202
                                showError("There was a problem deleting your file: "
1203
                                                + exception.getMessage(), bundle);
1204
                        }
1205
                }
1206
        }
1207

    
1208
        private class VersionRestoreTask extends
1209
                        AsyncTask<String, Void, HttpBundle> {
1210

    
1211
                private CloudServersException exception;
1212

    
1213
                protected void onPreExecute() {
1214
                        showDialog();
1215
                }
1216

    
1217
                @Override
1218
                protected HttpBundle doInBackground(String... arg0) {
1219
                        HttpBundle bundle = null;
1220
                        try {
1221
                                bundle = restoreVersion(arg0[0]);
1222
                        } catch (CloudServersException e) {
1223
                                e.printStackTrace();
1224
                                exception = e;
1225
                        }
1226

    
1227
                        return bundle;
1228
                }
1229

    
1230
                @Override
1231
                protected void onPostExecute(HttpBundle bundle) {
1232
                        hideDialog();
1233
                        HttpResponse response = null;
1234
                        if (bundle != null)
1235
                                response = bundle.getResponse();
1236
                        if (response != null) {
1237
                                int statusCode = response.getStatusLine().getStatusCode();
1238
                                if (statusCode == 204 || statusCode == 202) {
1239
                                        hideDialog();
1240
                                        setResult(99);
1241
                                        finish();
1242
                                } else {
1243
                                        CloudServersException cse = parseCloudServersException(response);
1244
                                        if ("".equals(cse.getMessage())) {
1245
                                                showError("There was a problem deleting your File.",
1246
                                                                bundle);
1247
                                        } else {
1248
                                                showError("There was a problem deleting your file: "
1249
                                                                + cse.getMessage(), bundle);
1250
                                        }
1251
                                }
1252
                        } else if (exception != null) {
1253
                                showError("There was a problem deleting your file: "
1254
                                                + exception.getMessage(), bundle);
1255
                        }
1256
                }
1257
        }
1258

    
1259
        public HttpBundle saveObject() throws CloudServersException {
1260
                Map<String, String> headers = new HashMap<String, String>();
1261
                if (objects.getMetadata() != null)
1262
                        for (Entry<String, String> entry : objects.getMetadata().entrySet()) {
1263
                                headers.put("X-Object-Meta-" + entry.getKey(), entry.getValue());
1264
                        }
1265
                for (String s : metadataRemoved) {
1266
                        headers.put("X-Object-Meta-" + s, "~");
1267
                }
1268
                if (!isFolder())
1269
                        headers.put("X-Object-Public", String.valueOf(objects.isPublicf()));
1270
                String read = "";
1271
                String write = "";
1272
                for (Permission p : objects.getPermissions()) {
1273
                        if (p.isWrite()) {
1274
                                if (!write.equals("")) {
1275
                                        write = write + ",";
1276
                                }
1277
                                write = write
1278
                                                + (p.getGroup() == null ? p.getUser() : p.getGroup());
1279
                        } else if (p.isRead()) {
1280
                                if (!read.equals("")) {
1281
                                        read = read + ",";
1282
                                }
1283
                                read = read
1284
                                                + (p.getGroup() == null ? p.getUser() : p.getGroup());
1285
                        }
1286

    
1287
                }
1288
                Log.d(LOG, "read:" + read);
1289
                Log.d(LOG, "write:" + write);
1290
                String permString = "";
1291
                if (!"".equals(read)) {
1292
                        permString = "read=" + read;
1293
                }
1294
                if (!"".equals(write)) {
1295
                        if (!"".equals(permString))
1296
                                permString = permString + ";write=" + write;
1297
                        else
1298
                                permString = "write=" + write;
1299
                }
1300
                Log.d(LOG, permString);
1301
                if (!"".equals(permString)) {
1302
                        headers.put("X-Object-Sharing", permString);
1303
                }
1304
                HttpBundle b = new ContainerObjectManager(getApplicationContext())
1305
                                .updateObject(objects.getContainerName(), objects.getCName(),
1306
                                                "", null, headers, otherUser);
1307
                Log.i(LOG, "response:"
1308
                                + b.getResponse().getStatusLine().getStatusCode());
1309
                return b;
1310
        }
1311

    
1312
        public HttpBundle restoreVersion(String version)
1313
                        throws CloudServersException {
1314
                Log.i(LOG, "Update version:" + version);
1315
                Map<String, String> headers = new HashMap<String, String>();
1316

    
1317
                headers.put("X-Source-Object", "/" + objects.getContainerName() + "/"
1318
                                + objects.getCName());
1319
                headers.put("X-Source-Version", version);
1320
                headers.put("Content-Range", "bytes 0-/*");
1321
                HttpBundle b = new ContainerObjectManager(getApplicationContext())
1322
                                .updateObject(objects.getContainerName(), objects.getCName(),
1323
                                                "", "text/plain; charset=UTF-8", headers, otherUser);
1324
                Log.i(LOG, "response:"
1325
                                + b.getResponse().getStatusLine().getStatusCode());
1326
                return b;
1327
        }
1328

    
1329
}