- removed uneccessary improts
[pub/Android/ownCloud.git] / src / com / owncloud / android / operations / DownloadFileOperation.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012-2013 ownCloud Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 package com.owncloud.android.operations;
19
20 import java.io.File;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.Set;
24 import java.util.concurrent.atomic.AtomicBoolean;
25
26 import com.owncloud.android.datamodel.OCFile;
27 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
28 import com.owncloud.android.lib.common.OwnCloudClient;
29 import com.owncloud.android.lib.common.operations.OperationCancelledException;
30 import com.owncloud.android.lib.common.operations.RemoteOperation;
31 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
32 import com.owncloud.android.lib.common.utils.Log_OC;
33 import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation;
34 import com.owncloud.android.utils.FileStorageUtils;
35
36 import android.accounts.Account;
37 import android.webkit.MimeTypeMap;
38
39 /**
40 * Remote mDownloadOperation performing the download of a file to an ownCloud server
41 *
42 * @author David A. Velasco
43 * @author masensio
44 */
45 public class DownloadFileOperation extends RemoteOperation {
46
47 private static final String TAG = DownloadFileOperation.class.getSimpleName();
48
49 private Account mAccount;
50 private OCFile mFile;
51 private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
52 private long mModificationTimestamp = 0;
53 private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
54
55 private DownloadRemoteFileOperation mDownloadOperation;
56
57
58 public DownloadFileOperation(Account account, OCFile file) {
59 if (account == null)
60 throw new IllegalArgumentException("Illegal null account in DownloadFileOperation creation");
61 if (file == null)
62 throw new IllegalArgumentException("Illegal null file in DownloadFileOperation creation");
63
64 mAccount = account;
65 mFile = file;
66
67 }
68
69
70 public Account getAccount() {
71 return mAccount;
72 }
73
74 public OCFile getFile() {
75 return mFile;
76 }
77
78 public String getSavePath() {
79 String path = mFile.getStoragePath(); // re-downloads should be done over the original file
80 if (path != null && path.length() > 0) {
81 return path;
82 }
83 return FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile);
84 }
85
86 public String getTmpPath() {
87 return FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
88 }
89
90 public String getTmpFolder() {
91 return FileStorageUtils.getTemporalPath(mAccount.name);
92 }
93
94 public String getRemotePath() {
95 return mFile.getRemotePath();
96 }
97
98 public String getMimeType() {
99 String mimeType = mFile.getMimetype();
100 if (mimeType == null || mimeType.length() <= 0) {
101 try {
102 mimeType = MimeTypeMap.getSingleton()
103 .getMimeTypeFromExtension(
104 mFile.getRemotePath().substring(mFile.getRemotePath().lastIndexOf('.') + 1));
105 } catch (IndexOutOfBoundsException e) {
106 Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + mFile.getRemotePath());
107 }
108 }
109 if (mimeType == null) {
110 mimeType = "application/octet-stream";
111 }
112 return mimeType;
113 }
114
115 public long getSize() {
116 return mFile.getFileLength();
117 }
118
119 public long getModificationTimestamp() {
120 return (mModificationTimestamp > 0) ? mModificationTimestamp : mFile.getModificationTimestamp();
121 }
122
123 @Override
124 protected RemoteOperationResult run(OwnCloudClient client) {
125 RemoteOperationResult result = null;
126 File newFile = null;
127 boolean moved = true;
128
129 /// download will be performed to a temporal file, then moved to the final location
130 File tmpFile = new File(getTmpPath());
131
132 String tmpFolder = getTmpFolder();
133
134 /// perform the download
135 synchronized(mCancellationRequested) {
136 if (mCancellationRequested.get()) {
137 return new RemoteOperationResult(new OperationCancelledException());
138 }
139 }
140
141 mDownloadOperation = new DownloadRemoteFileOperation(mFile.getRemotePath(), tmpFolder);
142 Iterator<OnDatatransferProgressListener> listener = mDataTransferListeners.iterator();
143 while (listener.hasNext()) {
144 mDownloadOperation.addDatatransferProgressListener(listener.next());
145 }
146 result = mDownloadOperation.execute(client);
147
148 if (result.isSuccess()) {
149 mModificationTimestamp = mDownloadOperation.getModificationTimestamp();
150 newFile = new File(getSavePath());
151 newFile.getParentFile().mkdirs();
152 moved = tmpFile.renameTo(newFile);
153
154 if (!moved)
155 result = new RemoteOperationResult(RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED);
156 }
157 Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage());
158
159
160 return result;
161 }
162
163 public void cancel() {
164 mCancellationRequested.set(true); // atomic set; there is no need of synchronizing it
165 if (mDownloadOperation != null) {
166 mDownloadOperation.cancel();
167 }
168 }
169
170
171 public void addDatatransferProgressListener (OnDatatransferProgressListener listener) {
172 synchronized (mDataTransferListeners) {
173 mDataTransferListeners.add(listener);
174 }
175 }
176
177 public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
178 synchronized (mDataTransferListeners) {
179 mDataTransferListeners.remove(listener);
180 }
181 }
182
183 }