package com.rackspacecloud.android;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.rackspace.cloud.android.R;
import com.rackspace.cloud.files.api.client.ContainerObjectManager;
import com.rackspace.cloud.files.api.client.ContainerObjects;
import com.rackspace.cloud.servers.api.client.CloudServersException;
import com.rackspace.cloud.servers.api.client.http.HttpBundle;
/**
*
* @author Phillip Toohill
*
*/
public class ContainerObjectDetails extends CloudActivity {
private static final int deleteObject = 0;
private final String DOWNLOAD_DIRECTORY = "/RackspaceCloud";
private ContainerObjects objects;
private String containerNames;
private String cdnURL;
private String cdnEnabled;
public String LOG = "ViewObject";
private int bConver = 1048576;
private int kbConver = 1024;
private double megaBytes;
private double kiloBytes;
public Button previewButton;
public Button downloadButton;
private Boolean isDownloaded;
private AndroidCloudApplication app;
private DeleteObjectListenerTask deleteObjTask;
private DownloadObjectListenerTask downloadObjTask;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
trackPageView(GoogleAnalytics.PAGE_STORAGE_OBJECT);
objects = (ContainerObjects) this.getIntent().getExtras().get("container");
containerNames = (String) this.getIntent().getExtras().get("containerNames");
cdnURL = (String) this.getIntent().getExtras().get("cdnUrl");
cdnEnabled = (String) this.getIntent().getExtras().get("isCdnEnabled");
setContentView(R.layout.viewobject);
restoreState(savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("container", objects);
outState.putBoolean("isDownloaded", isDownloaded);
}
protected void restoreState(Bundle state) {
super.restoreState(state);
/*
* need reference to the app so you can access curDirFiles
* as well as processing status
*/
app = (AndroidCloudApplication)this.getApplication();
if (state != null && state.containsKey("container")) {
objects = (ContainerObjects) state.getSerializable("container");
}
loadObjectData();
if ( cdnEnabled.equals("true")) {
this.previewButton = (Button) findViewById(R.id.preview_button);
previewButton.setOnClickListener(new MyOnClickListener());
} else {
this.previewButton = (Button) findViewById(R.id.preview_button);
previewButton.setVisibility(View.GONE);
}
if (state != null && state.containsKey("isDownloaded")){
isDownloaded = state.getBoolean("isDownloaded");
}
else{
isDownloaded = fileIsDownloaded();
}
this.downloadButton = (Button) findViewById(R.id.download_button);
if ( isDownloaded ) {
downloadButton.setText("Open File");
} else {
downloadButton.setText("Download File");
}
downloadButton.setOnClickListener(new MyOnClickListener());
if(app.isDeletingObject()){
deleteObjTask = new DeleteObjectListenerTask();
deleteObjTask.execute();
}
if(app.isDownloadingObject()){
downloadObjTask = new DownloadObjectListenerTask();
downloadObjTask.execute();
}
}
@Override
protected void onStop(){
super.onStop();
/*
* Need to stop running listener task
* if we exit
*/
if(deleteObjTask != null){
deleteObjTask.cancel(true);
}
if(downloadObjTask != null){
downloadObjTask.cancel(true);
}
}
private void loadObjectData() {
//Object Name
TextView name = (TextView) findViewById(R.id.view_container_name);
name.setText(objects.getCName().toString());
//File size
if (objects.getBytes() >= bConver) {
megaBytes = Math.abs(objects.getBytes()/bConver + 0.2);
TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
sublabel.setText(megaBytes + " MB");
} else if (objects.getBytes() >= kbConver){
kiloBytes = Math.abs(objects.getBytes()/kbConver + 0.2);
TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
sublabel.setText(kiloBytes + " KB");
} else {
TextView sublabel = (TextView) findViewById(R.id.view_file_bytes);
sublabel.setText(objects.getBytes() + " B");
}
//Content Type
TextView cType = (TextView) findViewById(R.id.view_content_type);
cType.setText(objects.getContentType().toString());
//Last Modification date
String strDate = objects.getLastMod();
strDate = strDate.substring(0, strDate.indexOf('T'));
TextView lastmod = (TextView) findViewById(R.id.view_file_modification);
lastmod.setText(strDate);
}
private class MyOnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
if(v.equals(findViewById(R.id.preview_button))){
Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(cdnURL + "/" + objects.getCName()));
startActivity(viewIntent);
}
/*
* need to perform different functions based on if
* the file is in the devices filesystem
*/
if(v.equals(findViewById(R.id.download_button))){
if(!isDownloaded){
if(storageIsReady()){
new ContainerObjectDownloadTask().execute();
}
else{
showAlert("Error", "Storage not found.");
}
}
else{
openFile();
}
}
}
}
//Create the Menu options
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.container_object_list_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete_object:
showDialog(deleteObject);
return true;
case R.id.refresh:
loadObjectData();
return true;
}
return false;
}
@Override
protected Dialog onCreateDialog(int id ) {
switch (id) {
case deleteObject:
return new AlertDialog.Builder(ContainerObjectDetails.this)
.setIcon(R.drawable.alert_dialog_icon)
.setTitle("Delete File")
.setMessage("Are you sure you want to delete this file?")
.setPositiveButton("Delete File", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// User clicked OK so do some stuff
trackEvent(GoogleAnalytics.CATEGORY_FILE, GoogleAnalytics.EVENT_DELETE, "", -1);
new ContainerObjectDeleteTask().execute((Void[]) null);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// User clicked Cancel so do some stuff
}
})
.create();
}
return null;
}
/**
* @return the file
*/
public ContainerObjects getViewFile() {
return objects;
}
/**
* @param File the file to set
*/
public void setViewFile(ContainerObjects object) {
this.objects = object;
}
/*
* returns false if external storage is not avaliable
* (if its mounted, missing, read-only, etc)
* from: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
*/
private boolean storageIsReady(){
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
return mExternalStorageAvailable && mExternalStorageWriteable;
}
private boolean fileIsDownloaded(){
if(storageIsReady()){
String fileName = Environment.getExternalStorageDirectory().getPath() + "/RackspaceCloud/" + objects.getCName();
File f = new File(fileName);
return f.isFile();
}
return false;
}
private void openFile(){
File object = new File(Environment.getExternalStorageDirectory().getPath() + "/RackspaceCloud/" + objects.getCName());
Intent myIntent = new Intent(android.content.Intent.ACTION_VIEW);
File file = new File(object.getAbsolutePath());
String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
myIntent.setDataAndType(Uri.fromFile(file),mimetype);
//myIntent.setData(Uri.fromFile(file));
try{
startActivity(myIntent);
}
catch(Exception e){
Toast.makeText(this, "Could not open file.", Toast.LENGTH_SHORT).show();
}
}
private boolean writeFile(byte[] data){
String directoryName = Environment.getExternalStorageDirectory().getPath() + DOWNLOAD_DIRECTORY;
File f = new File(directoryName);
if(!f.isDirectory()){
if(!f.mkdir()){
return false;
}
}
String filename = directoryName + "/" + objects.getCName();
File object = new File(filename);
BufferedOutputStream bos = null;
try{
FileOutputStream fos = new FileOutputStream(object);
bos = new BufferedOutputStream(fos);
bos.write(data);
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
finally{
if(bos != null){
try {
bos.flush();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return true;
}
//Task's
private class ContainerObjectDeleteTask extends AsyncTask<Void, Void, HttpBundle> {
private CloudServersException exception;
protected void onPreExecute(){
showDialog();
app.setDeleteingObject(true);
deleteObjTask = new DeleteObjectListenerTask();
deleteObjTask.execute();
}
@Override
protected HttpBundle doInBackground(Void... arg0) {
HttpBundle bundle = null;
try {
bundle = (new ContainerObjectManager(getContext())).deleteObject(containerNames, objects.getCName() );
} catch (CloudServersException e) {
exception = e;
}
return bundle;
}
@Override
protected void onPostExecute(HttpBundle bundle) {
app.setDeleteingObject(false);
hideDialog();
if (bundle != null) { //Otherwise a listener later on shows an error message
HttpResponse response = bundle.getResponse();
if (response != null) {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 204) {
//handled by listener
} else {
CloudServersException cse = parseCloudServersException(response);
if ("".equals(cse.getMessage())) {
showError("There was a problem deleting your File.", bundle);
} else {
showError("There was a problem deleting your file: " + cse.getMessage(), bundle);
}
}
} else if (exception != null) {
showError("There was a problem deleting your file: " + exception.getMessage(), bundle);
}
}
}
}
private class ContainerObjectDownloadTask extends AsyncTask<Void, Void, HttpBundle> {
private CloudServersException exception;
@Override
protected void onPreExecute(){
showDialog();
app.setDownloadingObject(true);
downloadObjTask = new DownloadObjectListenerTask();
downloadObjTask.execute();
}
@Override
protected HttpBundle doInBackground(Void... arg0) {
HttpBundle bundle = null;
try {
bundle = (new ContainerObjectManager(getContext())).getObject(containerNames, objects.getCName());
} catch (CloudServersException e) {
exception = e;
}
return bundle;
}
@Override
protected void onPostExecute(HttpBundle bundle) {
app.setDownloadingObject(false);
hideDialog();
if (bundle != null) { //Otherwise a listener later on shows an error message
HttpResponse response = bundle.getResponse();
if (response != null) {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
setResult(Activity.RESULT_OK);
HttpEntity entity = response.getEntity();
app.setDownloadedEntity(entity);
} else {
CloudServersException cse = parseCloudServersException(response);
if ("".equals(cse.getMessage())) {
showError("There was a problem downloading your File.", bundle);
} else {
showError("There was a problem downloading your file: " + cse.getMessage(), bundle);
}
}
} else if (exception != null) {
showError("There was a problem downloading your file: " + exception.getMessage(), bundle);
}
}
}
}
private class DeleteObjectListenerTask extends
AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... arg1) {
while(app.isDeletingObject()){
// wait for process to finish
// or have it be canceled
if(deleteObjTask.isCancelled()){
return null;
}
}
return null;
}
/*
* when no longer processing, time to load
* the new files
*/
@Override
protected void onPostExecute(Void arg1) {
hideDialog();
setResult(99);
finish();
}
}
private class DownloadObjectListenerTask extends
AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... arg1) {
while(app.isDownloadingObject()){
// wait for process to finish
// or have it be canceled
if(downloadObjTask.isCancelled()){
return null;
}
}
return null;
}
/*
* when no longer processing, time to load
* the new files
*/
@Override
protected void onPostExecute(Void arg1) {
hideDialog();
try {
if(writeFile(EntityUtils.toByteArray(app.getDownloadedEntity()))){
downloadButton.setText("Open File");
isDownloaded = true;
}
else{
showAlert("Error", "There was a problem downloading your file.");
}
} catch (IOException e) {
showAlert("Error", "There was a problem downloading your file.");
e.printStackTrace();
} catch (Exception e) {
showAlert("Error", "There was a problem downloading your file.");
e.printStackTrace();
}
}
}
}