Fixed crash when the device is turned while the warning dialog about server certifica...
[pub/Android/ownCloud.git] / src / com / owncloud / android / operations / UploadFileOperation.java
1 /* ownCloud Android client application
2 * Copyright (C) 2012 Bartek Przybylski
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 as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 package com.owncloud.android.operations;
20
21 import java.io.File;
22 import java.io.IOException;
23
24 import org.apache.commons.httpclient.HttpException;
25 import org.apache.commons.httpclient.methods.PutMethod;
26 import org.apache.http.HttpStatus;
27
28 import com.owncloud.android.operations.RemoteOperation;
29 import com.owncloud.android.operations.RemoteOperationResult;
30
31 import eu.alefzero.webdav.FileRequestEntity;
32 import eu.alefzero.webdav.OnDatatransferProgressListener;
33 import eu.alefzero.webdav.WebdavClient;
34 import eu.alefzero.webdav.WebdavUtils;
35 import android.util.Log;
36 import android.webkit.MimeTypeMap;
37
38 /**
39 * Remote operation performing the upload of a file to an ownCloud server
40 *
41 * @author David A. Velasco
42 */
43 public class UploadFileOperation extends RemoteOperation {
44
45 private static final String TAG = UploadFileOperation.class.getCanonicalName();
46
47 private String mLocalPath = null;
48 private String mRemotePath = null;
49 private String mMimeType = null;
50 private boolean mIsInstant = false;
51 private boolean mForceOverwrite = false;
52 private OnDatatransferProgressListener mDataTransferListener = null;
53
54
55 public String getLocalPath() {
56 return mLocalPath;
57 }
58
59 public String getRemotePath() {
60 return mRemotePath;
61 }
62
63 public String getMimeType() {
64 return mMimeType;
65 }
66
67
68 public boolean isInstant() {
69 return mIsInstant;
70 }
71
72
73 public boolean getForceOverwrite() {
74 return mForceOverwrite;
75 }
76
77
78 public OnDatatransferProgressListener getDataTransferListener() {
79 return mDataTransferListener ;
80 }
81
82
83 public UploadFileOperation( String localPath,
84 String remotePath,
85 String mimeType,
86 boolean isInstant,
87 boolean forceOverwrite,
88 OnDatatransferProgressListener dataTransferProgressListener) {
89 mLocalPath = localPath;
90 mRemotePath = remotePath;
91 mMimeType = mimeType;
92 if (mMimeType == null) {
93 try {
94 mMimeType = MimeTypeMap.getSingleton()
95 .getMimeTypeFromExtension(
96 localPath.substring(localPath.lastIndexOf('.') + 1));
97 } catch (IndexOutOfBoundsException e) {
98 Log.e(TAG, "Trying to find out MIME type of a file without extension: " + localPath);
99 }
100 }
101 if (mMimeType == null) {
102 mMimeType = "application/octet-stream";
103 }
104 mIsInstant = isInstant;
105 mForceOverwrite = forceOverwrite;
106 mDataTransferListener = dataTransferProgressListener;
107 }
108
109 @Override
110 protected RemoteOperationResult run(WebdavClient client) {
111 RemoteOperationResult result = null;
112 boolean nameCheckPassed = false;
113 try {
114 /// rename the file to upload, if necessary
115 if (!mForceOverwrite) {
116 mRemotePath = getAvailableRemotePath(client, mRemotePath);
117 }
118
119 /// perform the upload
120 nameCheckPassed = true;
121 int status = uploadFile(client);
122 result = new RemoteOperationResult(isSuccess(status), status);
123 Log.i(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage());
124
125 } catch (Exception e) {
126 result = new RemoteOperationResult(e);
127 Log.e(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " + result.getLogMessage() + (nameCheckPassed?"":" (while checking file existence in server)"), e);
128
129 }
130
131 return result;
132 }
133
134
135 public boolean isSuccess(int status) {
136 return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT));
137 }
138
139
140 protected int uploadFile(WebdavClient client) throws HttpException, IOException {
141 int status = -1;
142 PutMethod put = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
143
144 try {
145 File f = new File(mLocalPath);
146 FileRequestEntity entity = new FileRequestEntity(f, mMimeType);
147 entity.setOnDatatransferProgressListener(mDataTransferListener);
148 put.setRequestEntity(entity);
149 status = client.executeMethod(put);
150 client.exhaustResponse(put.getResponseBodyAsStream());
151
152 } finally {
153 put.releaseConnection(); // let the connection available for other methods
154 }
155 return status;
156 }
157
158 /**
159 * Checks if remotePath does not exist in the server and returns it, or adds a suffix to it in order to avoid the server
160 * file is overwritten.
161 *
162 * @param string
163 * @return
164 */
165 private String getAvailableRemotePath(WebdavClient wc, String remotePath) throws Exception {
166 boolean check = wc.existsFile(remotePath);
167 if (!check) {
168 return remotePath;
169 }
170
171 int pos = remotePath.lastIndexOf(".");
172 String suffix = "";
173 String extension = "";
174 if (pos >= 0) {
175 extension = remotePath.substring(pos+1);
176 remotePath = remotePath.substring(0, pos);
177 }
178 int count = 2;
179 do {
180 suffix = " (" + count + ")";
181 if (pos >= 0)
182 check = wc.existsFile(remotePath + suffix + "." + extension);
183 else
184 check = wc.existsFile(remotePath + suffix);
185 count++;
186 } while (check);
187
188 if (pos >=0) {
189 return remotePath + suffix + "." + extension;
190 } else {
191 return remotePath + suffix;
192 }
193 }
194
195 }