1
0
mirror of https://github.com/owncloud/android-library.git synced 2026-08-20 12:52:53 +00:00

Reordered packages

This commit is contained in:
David A. Velasco
2014-02-14 12:04:41 +01:00
parent 815fbba486
commit 6c4d342610
54 changed files with 208 additions and 303 deletions
@@ -0,0 +1,101 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
* Copyright (C) 2012 Bartek Przybylski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.Random;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PutMethod;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity;
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
import com.owncloud.android.lib.common.network.WebdavUtils;
import android.util.Log;
public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation {
public static final long CHUNK_SIZE = 1024000;
private static final String OC_CHUNKED_HEADER = "OC-Chunked";
private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName();
public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) {
super(storagePath, remotePath, mimeType);
}
@Override
protected int uploadFile(OwnCloudClient client) throws HttpException, IOException {
int status = -1;
FileChannel channel = null;
RandomAccessFile raf = null;
try {
File file = new File(mStoragePath);
raf = new RandomAccessFile(file, "r");
channel = raf.getChannel();
mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
//((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(getDataTransferListeners());
synchronized (mDataTransferListeners) {
((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners);
}
long offset = 0;
String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ;
long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE);
for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
if (mPutMethod != null) {
mPutMethod.releaseConnection(); // let the connection available for other methods
}
mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex);
mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER);
((ChunkFromFileChannelRequestEntity)mEntity).setOffset(offset);
mPutMethod.setRequestEntity(mEntity);
status = client.executeMethod(mPutMethod);
client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
Log.d(TAG, "Upload of " + mStoragePath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
if (!isSuccess(status))
break;
}
} finally {
if (channel != null)
channel.close();
if (raf != null)
raf.close();
if (mPutMethod != null)
mPutMethod.releaseConnection(); // let the connection available for other methods
}
return status;
}
}
@@ -0,0 +1,117 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
/**
* Remote operation performing the creation of a new folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*
*/
public class CreateRemoteFolderOperation extends RemoteOperation {
private static final String TAG = CreateRemoteFolderOperation.class.getSimpleName();
private static final int READ_TIMEOUT = 10000;
private static final int CONNECTION_TIMEOUT = 5000;
protected String mRemotePath;
protected boolean mCreateFullPath;
/**
* Constructor
*
* @param remotePath Full path to the new directory to create in the remote server.
* @param createFullPath 'True' means that all the ancestor folders should be created if don't exist yet.
*/
public CreateRemoteFolderOperation(String remotePath, boolean createFullPath) {
mRemotePath = remotePath;
mCreateFullPath = createFullPath;
}
/**
* Performs the operation
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
MkColMethod mkcol = null;
boolean noInvalidChars = FileUtils.isValidPath(mRemotePath);
if (noInvalidChars) {
try {
mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
if (!mkcol.succeeded() && mkcol.getStatusCode() == HttpStatus.SC_CONFLICT && mCreateFullPath) {
result = createParentFolder(FileUtils.getParentPath(mRemotePath), client);
status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); // second (and last) try
}
result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders());
Log.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
client.exhaustResponse(mkcol.getResponseBodyAsStream());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage(), e);
} finally {
if (mkcol != null)
mkcol.releaseConnection();
}
} else {
result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
}
return result;
}
private RemoteOperationResult createParentFolder(String parentPath, OwnCloudClient client) {
RemoteOperation operation = new CreateRemoteFolderOperation(parentPath,
mCreateFullPath);
return operation.execute(client);
}
}
@@ -0,0 +1,183 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.OperationCancelledException;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
/**
* Remote operation performing the download of a remote file in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
public class DownloadRemoteFileOperation extends RemoteOperation {
private static final String TAG = DownloadRemoteFileOperation.class.getSimpleName();
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
private long mModificationTimestamp = 0;
private GetMethod mGet;
private String mRemotePath;
private String mDownloadFolderPath;
public DownloadRemoteFileOperation(String remotePath, String downloadFolderPath) {
mRemotePath = remotePath;
mDownloadFolderPath = downloadFolderPath;
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
/// download will be performed to a temporal file, then moved to the final location
File tmpFile = new File(getTmpPath());
/// perform the download
try {
tmpFile.getParentFile().mkdirs();
int status = downloadFile(client, tmpFile);
result = new RemoteOperationResult(isSuccess(status), status, (mGet != null ? mGet.getResponseHeaders() : null));
Log.i(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + result.getLogMessage(), e);
}
return result;
}
protected int downloadFile(OwnCloudClient client, File targetFile) throws HttpException, IOException, OperationCancelledException {
int status = -1;
boolean savedFile = false;
mGet = new GetMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
Iterator<OnDatatransferProgressListener> it = null;
FileOutputStream fos = null;
try {
status = client.executeMethod(mGet);
if (isSuccess(status)) {
targetFile.createNewFile();
BufferedInputStream bis = new BufferedInputStream(mGet.getResponseBodyAsStream());
fos = new FileOutputStream(targetFile);
long transferred = 0;
Header contentLength = mGet.getResponseHeader("Content-Length");
long totalToTransfer = (contentLength != null && contentLength.getValue().length() >0) ? Long.parseLong(contentLength.getValue()) : 0;
byte[] bytes = new byte[4096];
int readResult = 0;
while ((readResult = bis.read(bytes)) != -1) {
synchronized(mCancellationRequested) {
if (mCancellationRequested.get()) {
mGet.abort();
throw new OperationCancelledException();
}
}
fos.write(bytes, 0, readResult);
transferred += readResult;
synchronized (mDataTransferListeners) {
it = mDataTransferListeners.iterator();
while (it.hasNext()) {
it.next().onTransferProgress(readResult, transferred, totalToTransfer, targetFile.getName());
}
}
}
savedFile = true;
Header modificationTime = mGet.getResponseHeader("Last-Modified");
if (modificationTime != null) {
Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue());
mModificationTimestamp = (d != null) ? d.getTime() : 0;
}
} else {
client.exhaustResponse(mGet.getResponseBodyAsStream());
}
} finally {
if (fos != null) fos.close();
if (!savedFile && targetFile.exists()) {
targetFile.delete();
}
mGet.releaseConnection(); // let the connection available for other methods
}
return status;
}
private boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
private String getTmpPath() {
return mDownloadFolderPath + mRemotePath;
}
public void addDatatransferProgressListener (OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.add(listener);
}
}
public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.remove(listener);
}
}
public void cancel() {
mCancellationRequested.set(true); // atomic set; there is no need of synchronizing it
}
public long getModificationTimestamp() {
return mModificationTimestamp;
}
}
@@ -0,0 +1,104 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.HeadMethod;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import android.content.Context;
import android.net.ConnectivityManager;
import android.util.Log;
/**
* Operation to check the existence or absence of a path in a remote server.
*
* @author David A. Velasco
*/
public class ExistenceCheckRemoteOperation extends RemoteOperation {
/** Maximum time to wait for a response from the server in MILLISECONDs. */
public static final int TIMEOUT = 10000;
private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName();
private String mPath;
private Context mContext;
private boolean mSuccessIfAbsent;
/**
* Full constructor. Success of the operation will depend upon the value of successIfAbsent.
*
* @param path Path to append to the URL owned by the client instance.
* @param context Android application context.
* @param successIfAbsent When 'true', the operation finishes in success if the path does NOT exist in the remote server (HTTP 404).
*/
public ExistenceCheckRemoteOperation(String path, Context context, boolean successIfAbsent) {
mPath = (path != null) ? path : "";
mContext = context;
mSuccessIfAbsent = successIfAbsent;
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
if (!isOnline()) {
return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
}
RemoteOperationResult result = null;
HeadMethod head = null;
try {
head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath));
int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
client.exhaustResponse(head.getResponseBodyAsStream());
boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
result = new RemoteOperationResult(success, status, head.getResponseHeaders());
Log.d(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":""));
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException());
} finally {
if (head != null)
head.releaseConnection();
}
return result;
}
private boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm != null && cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
}
@@ -0,0 +1,78 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.io.File;
import android.util.Log;
public class FileUtils {
public static final String PATH_SEPARATOR = "/";
public static String getParentPath(String remotePath) {
String parentPath = new File(remotePath).getParent();
parentPath = parentPath.endsWith(PATH_SEPARATOR) ? parentPath : parentPath + PATH_SEPARATOR;
return parentPath;
}
/**
* Validate the fileName to detect if contains any forbidden character: / , \ , < , > , : , " , | , ? , *
* @param fileName
* @return
*/
public static boolean isValidName(String fileName) {
boolean result = true;
Log.d("FileUtils", "fileName =======" + fileName);
if (fileName.contains(PATH_SEPARATOR) ||
fileName.contains("\\") || fileName.contains("<") || fileName.contains(">") ||
fileName.contains(":") || fileName.contains("\"") || fileName.contains("|") ||
fileName.contains("?") || fileName.contains("*")) {
result = false;
}
return result;
}
/**
* Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , ? , *
* @param path
* @return
*/
public static boolean isValidPath(String path) {
boolean result = true;
Log.d("FileUtils", "path ....... " + path);
if (path.contains("\\") || path.contains("<") || path.contains(">") ||
path.contains(":") || path.contains("\"") || path.contains("|") ||
path.contains("?") || path.contains("*")) {
result = false;
}
return result;
}
}
@@ -0,0 +1,114 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.util.ArrayList;
import org.apache.http.HttpStatus;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavEntry;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
/**
* Remote operation performing the read a file from the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
public class ReadRemoteFileOperation extends RemoteOperation {
private static final String TAG = ReadRemoteFileOperation.class.getSimpleName();
private static final int SYNC_READ_TIMEOUT = 10000;
private static final int SYNC_CONNECTION_TIMEOUT = 5000;
private String mRemotePath;
/**
* Constructor
*
* @param remotePath Remote path of the file.
*/
public ReadRemoteFileOperation(String remotePath) {
mRemotePath = remotePath;
}
/**
* Performs the read operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
PropFindMethod propfind = null;
RemoteOperationResult result = null;
/// take the duty of check the server for the current state of the file there
try {
propfind = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
DavConstants.PROPFIND_ALL_PROP,
DavConstants.DEPTH_0);
int status;
status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT);
boolean isMultiStatus = status == HttpStatus.SC_MULTI_STATUS;
if (isMultiStatus) {
// Parse response
MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getWebdavUri().getPath());
RemoteFile remoteFile = new RemoteFile(we);
ArrayList<Object> files = new ArrayList<Object>();
files.add(remoteFile);
// Result of the operation
result = new RemoteOperationResult(true, status, propfind.getResponseHeaders());
result.setData(files);
} else {
client.exhaustResponse(propfind.getResponseBodyAsStream());
result = new RemoteOperationResult(false, status, propfind.getResponseHeaders());
}
} catch (Exception e) {
result = new RemoteOperationResult(e);
e.printStackTrace();
Log.e(TAG, "Synchronizing file " + mRemotePath + ": " + result.getLogMessage(), result.getException());
} finally {
if (propfind != null)
propfind.releaseConnection();
}
return result;
}
}
@@ -0,0 +1,168 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.util.ArrayList;
import org.apache.http.HttpStatus;
import org.apache.jackrabbit.webdav.DavConstants;
import org.apache.jackrabbit.webdav.MultiStatus;
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavEntry;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
/**
* Remote operation performing the read of remote file or folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
public class ReadRemoteFolderOperation extends RemoteOperation {
private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName();
private String mRemotePath;
private ArrayList<Object> mFolderAndFiles;
/**
* Constructor
*
* @param remotePath Remote path of the file.
*/
public ReadRemoteFolderOperation(String remotePath) {
mRemotePath = remotePath;
}
/**
* Performs the read operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
PropFindMethod query = null;
try {
// remote request
query = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
DavConstants.PROPFIND_ALL_PROP,
DavConstants.DEPTH_1);
int status = client.executeMethod(query);
// check and process response
if (isMultiStatus(status)) {
// get data from remote folder
MultiStatus dataInServer = query.getResponseBodyAsMultiStatus();
readData(dataInServer, client);
// Result of the operation
result = new RemoteOperationResult(true, status, query.getResponseHeaders());
// Add data to the result
if (result.isSuccess()) {
result.setData(mFolderAndFiles);
}
} else {
// synchronization failed
client.exhaustResponse(query.getResponseBodyAsStream());
result = new RemoteOperationResult(false, status, query.getResponseHeaders());
}
} catch (Exception e) {
result = new RemoteOperationResult(e);
} finally {
if (query != null)
query.releaseConnection(); // let the connection available for other methods
if (result.isSuccess()) {
Log.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage());
} else {
if (result.isException()) {
Log.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(), result.getException());
} else {
Log.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage());
}
}
}
return result;
}
public boolean isMultiStatus(int status) {
return (status == HttpStatus.SC_MULTI_STATUS);
}
/**
* Read the data retrieved from the server about the contents of the target folder
*
*
* @param dataInServer Full response got from the server with the data of the target
* folder and its direct children.
* @param client Client instance to the remote server where the data were
* retrieved.
* @return
*/
private void readData(MultiStatus dataInServer, OwnCloudClient client) {
mFolderAndFiles = new ArrayList<Object>();
// parse data from remote folder
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getWebdavUri().getPath());
mFolderAndFiles.add(fillOCFile(we));
// loop to update every child
RemoteFile remoteFile = null;
for (int i = 1; i < dataInServer.getResponses().length; ++i) {
/// new OCFile instance with the data from the server
we = new WebdavEntry(dataInServer.getResponses()[i], client.getWebdavUri().getPath());
remoteFile = fillOCFile(we);
mFolderAndFiles.add(remoteFile);
}
}
/**
* Creates and populates a new {@link RemoteFile} object with the data read from the server.
*
* @param we WebDAV entry read from the server for a WebDAV resource (remote file or folder).
* @return New OCFile instance representing the remote resource described by we.
*/
private RemoteFile fillOCFile(WebdavEntry we) {
RemoteFile file = new RemoteFile(we.decodedPath());
file.setCreationTimestamp(we.createTimestamp());
file.setLength(we.contentLength());
file.setMimeType(we.contentType());
file.setModifiedTimestamp(we.modifiedTimestamp());
file.setEtag(we.etag());
return file;
}
}
@@ -0,0 +1,194 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.io.Serializable;
import android.os.Parcel;
import android.os.Parcelable;
import com.owncloud.android.lib.common.network.WebdavEntry;
/**
* Contains the data of a Remote File from a WebDavEntry
*
* @author masensio
*/
public class RemoteFile implements Parcelable, Serializable {
/** Generated - should be refreshed every time the class changes!! */
private static final long serialVersionUID = 532139091191390616L;
private String mRemotePath;
private String mMimeType;
private long mLength;
private long mCreationTimestamp;
private long mModifiedTimestamp;
private String mEtag;
/**
* Getters and Setters
*/
public String getRemotePath() {
return mRemotePath;
}
public void setRemotePath(String remotePath) {
this.mRemotePath = remotePath;
}
public String getMimeType() {
return mMimeType;
}
public void setMimeType(String mimeType) {
this.mMimeType = mimeType;
}
public long getLength() {
return mLength;
}
public void setLength(long length) {
this.mLength = length;
}
public long getCreationTimestamp() {
return mCreationTimestamp;
}
public void setCreationTimestamp(long creationTimestamp) {
this.mCreationTimestamp = creationTimestamp;
}
public long getModifiedTimestamp() {
return mModifiedTimestamp;
}
public void setModifiedTimestamp(long modifiedTimestamp) {
this.mModifiedTimestamp = modifiedTimestamp;
}
public String getEtag() {
return mEtag;
}
public void setEtag(String etag) {
this.mEtag = etag;
}
public RemoteFile() {
resetData();
}
/**
* Create new {@link RemoteFile} with given path.
*
* The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
*
* @param path The remote path of the file.
*/
public RemoteFile(String path) {
resetData();
if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) {
throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
}
mRemotePath = path;
}
public RemoteFile(WebdavEntry we) {
this(we.decodedPath());
this.setCreationTimestamp(we.createTimestamp());
this.setLength(we.contentLength());
this.setMimeType(we.contentType());
this.setModifiedTimestamp(we.modifiedTimestamp());
this.setEtag(we.etag());
}
/**
* Used internally. Reset all file properties
*/
private void resetData() {
mRemotePath = null;
mMimeType = null;
mLength = 0;
mCreationTimestamp = 0;
mModifiedTimestamp = 0;
mEtag = null;
}
/**
* Parcelable Methods
*/
public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() {
@Override
public RemoteFile createFromParcel(Parcel source) {
return new RemoteFile(source);
}
@Override
public RemoteFile[] newArray(int size) {
return new RemoteFile[size];
}
};
/**
* Reconstruct from parcel
*
* @param source The source parcel
*/
protected RemoteFile(Parcel source) {
readFromParcel(source);
}
public void readFromParcel (Parcel source) {
mRemotePath = source.readString();
mMimeType = source.readString();
mLength = source.readLong();
mCreationTimestamp = source.readLong();
mModifiedTimestamp = source.readLong();
mEtag = source.readString();
}
@Override
public int describeContents() {
return this.hashCode();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mRemotePath);
dest.writeString(mMimeType);
dest.writeLong(mLength);
dest.writeLong(mCreationTimestamp);
dest.writeLong(mModifiedTimestamp);
dest.writeString(mEtag);
}
}
@@ -0,0 +1,90 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
/**
* Remote operation performing the removal of a remote file or folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
public class RemoveRemoteFileOperation extends RemoteOperation {
private static final String TAG = RemoveRemoteFileOperation.class.getSimpleName();
private static final int REMOVE_READ_TIMEOUT = 10000;
private static final int REMOVE_CONNECTION_TIMEOUT = 5000;
private String mRemotePath;
/**
* Constructor
*
* @param remotePath RemotePath of the remote file or folder to remove from the server
*/
public RemoveRemoteFileOperation(String remotePath) {
mRemotePath = remotePath;
}
/**
* Performs the rename operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
DeleteMethod delete = null;
try {
delete = new DeleteMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT);
delete.getResponseBodyAsString(); // exhaust the response, although not interesting
result = new RemoteOperationResult((delete.succeeded() || status == HttpStatus.SC_NOT_FOUND), status, delete.getResponseHeaders());
Log.i(TAG, "Remove " + mRemotePath + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Remove " + mRemotePath + ": " + result.getLogMessage(), e);
} finally {
if (delete != null)
delete.releaseConnection();
}
return result;
}
}
@@ -0,0 +1,152 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.io.File;
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
/**
* Remote operation performing the rename of a remote file or folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
public class RenameRemoteFileOperation extends RemoteOperation {
private static final String TAG = RenameRemoteFileOperation.class.getSimpleName();
private static final int RENAME_READ_TIMEOUT = 10000;
private static final int RENAME_CONNECTION_TIMEOUT = 5000;
private String mOldName;
private String mOldRemotePath;
private String mNewName;
private String mNewRemotePath;
/**
* Constructor
*
* @param oldName Old name of the file.
* @param oldRemotePath Old remote path of the file.
* @param newName New name to set as the name of file.
* @param isFolder 'true' for folder and 'false' for files
*/
public RenameRemoteFileOperation(String oldName, String oldRemotePath, String newName, boolean isFolder) {
mOldName = oldName;
mOldRemotePath = oldRemotePath;
mNewName = newName;
String parent = (new File(mOldRemotePath)).getParent();
parent = (parent.endsWith(FileUtils.PATH_SEPARATOR)) ? parent : parent + FileUtils.PATH_SEPARATOR;
mNewRemotePath = parent + mNewName;
if (isFolder) {
mNewRemotePath += FileUtils.PATH_SEPARATOR;
}
}
/**
* Performs the rename operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
LocalMoveMethod move = null;
boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath);
if (noInvalidChars) {
try {
if (mNewName.equals(mOldName)) {
return new RemoteOperationResult(ResultCode.OK);
}
// check if a file with the new name already exists
if (client.existsFile(mNewRemotePath)) {
return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
}
move = new LocalMoveMethod( client.getWebdavUri() + WebdavUtils.encodePath(mOldRemotePath),
client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath));
int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT);
move.getResponseBodyAsString(); // exhaust response, although not interesting
result = new RemoteOperationResult(move.succeeded(), status, move.getResponseHeaders());
Log.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " + result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Rename " + mOldRemotePath + " to " + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + result.getLogMessage(), e);
} finally {
if (move != null)
move.releaseConnection();
}
} else {
result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
}
return result;
}
/**
* Move operation
*
*/
private class LocalMoveMethod extends DavMethodBase {
public LocalMoveMethod(String uri, String dest) {
super(uri);
addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest));
}
@Override
public String getName() {
return "MOVE";
}
@Override
protected boolean isSuccess(int status) {
return status == 201 || status == 204;
}
}
}
@@ -0,0 +1,154 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.http.HttpStatus;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.FileRequestEntity;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
import com.owncloud.android.lib.common.network.WebdavUtils;
import com.owncloud.android.lib.common.operations.OperationCancelledException;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
/**
* Remote operation performing the upload of a remote file to the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
public class UploadRemoteFileOperation extends RemoteOperation {
protected String mStoragePath;
protected String mRemotePath;
protected String mMimeType;
protected PutMethod mPutMethod = null;
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
protected RequestEntity mEntity = null;
public UploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) {
mStoragePath = storagePath;
mRemotePath = remotePath;
mMimeType = mimeType;
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
try {
// / perform the upload
synchronized (mCancellationRequested) {
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
} else {
mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
}
}
int status = uploadFile(client);
result = new RemoteOperationResult(isSuccess(status), status, (mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
} catch (Exception e) {
// TODO something cleaner with cancellations
if (mCancellationRequested.get()) {
result = new RemoteOperationResult(new OperationCancelledException());
} else {
result = new RemoteOperationResult(e);
}
}
return result;
}
public boolean isSuccess(int status) {
return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT));
}
protected int uploadFile(OwnCloudClient client) throws HttpException, IOException, OperationCancelledException {
int status = -1;
try {
File f = new File(mStoragePath);
mEntity = new FileRequestEntity(f, mMimeType);
synchronized (mDataTransferListeners) {
((ProgressiveDataTransferer)mEntity).addDatatransferProgressListeners(mDataTransferListeners);
}
mPutMethod.setRequestEntity(mEntity);
status = client.executeMethod(mPutMethod);
client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
} finally {
mPutMethod.releaseConnection(); // let the connection available for other methods
}
return status;
}
public Set<OnDatatransferProgressListener> getDataTransferListeners() {
return mDataTransferListeners;
}
public void addDatatransferProgressListener (OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.add(listener);
}
if (mEntity != null) {
((ProgressiveDataTransferer)mEntity).addDatatransferProgressListener(listener);
}
}
public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
synchronized (mDataTransferListeners) {
mDataTransferListeners.remove(listener);
}
if (mEntity != null) {
((ProgressiveDataTransferer)mEntity).removeDatatransferProgressListener(listener);
}
}
public void cancel() {
synchronized (mCancellationRequested) {
mCancellationRequested.set(true);
if (mPutMethod != null)
mPutMethod.abort();
}
}
}
@@ -0,0 +1,168 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.http.HttpStatus;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
/**
* Creates a new share. This allows sharing with a user or group or as a link.
*
* @author masensio
*
*/
public class CreateShareRemoteOperation extends RemoteOperation {
private static final String TAG = CreateShareRemoteOperation.class.getSimpleName();
private static final String PARAM_PATH = "path";
private static final String PARAM_SHARE_TYPE = "shareType";
private static final String PARAM_SHARE_WITH = "shareWith";
private static final String PARAM_PUBLIC_UPLOAD = "publicUpload";
private static final String PARAM_PASSWORD = "password";
private static final String PARAM_PERMISSIONS = "permissions";
private ArrayList<OCShare> mShares; // List of shares for result, one share in this case
private String mPath;
private ShareType mShareType;
private String mShareWith;
private boolean mPublicUpload;
private String mPassword;
private int mPermissions;
/**
* Constructor
* @param path Full path of the file/folder being shared. Mandatory argument
* @param shareType 0 = user, 1 = group, 3 = Public link. Mandatory argument
* @param shareWith User/group ID with who the file should be shared. This is mandatory for shareType of 0 or 1
* @param publicUpload If false (default) public cannot upload to a public shared folder.
* If true public can upload to a shared folder. Only available for public link shares
* @param password Password to protect a public link share. Only available for public link shares
* @param permissions 1 - Read only Default for “public” shares
* 2 - Update
* 4 - Create
* 8 - Delete
* 16- Re-share
* 31- All above Default for “private” shares
* For user or group shares.
* To obtain combinations, add the desired values together.
* For instance, for “Re-Share”, “delete”, “read”, “update”, add 16+8+2+1 = 27.
*/
public CreateShareRemoteOperation(String path, ShareType shareType, String shareWith, boolean publicUpload,
String password, int permissions) {
mPath = path;
mShareType = shareType;
mShareWith = shareWith;
mPublicUpload = publicUpload;
mPassword = password;
mPermissions = permissions;
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
int status = -1;
PostMethod post = null;
try {
// Post Method
post = new PostMethod(client.getBaseUri() + ShareUtils.SHAREAPI_ROUTE);
Log.d(TAG, "URL ------> " + client.getBaseUri() + ShareUtils.SHAREAPI_ROUTE);
post.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); // necessary for special characters
post.addParameter(PARAM_PATH, mPath);
post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue()));
post.addParameter(PARAM_SHARE_WITH, mShareWith);
post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload));
if (mPassword != null && mPassword.length() > 0) {
post.addParameter(PARAM_PASSWORD, mPassword);
}
post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions));
status = client.executeMethod(post);
if(isSuccess(status)) {
String response = post.getResponseBodyAsString();
Log.d(TAG, "Successful response: " + response);
result = new RemoteOperationResult(ResultCode.OK);
// Parse xml response --> obtain the response in ShareFiles ArrayList
// convert String into InputStream
InputStream is = new ByteArrayInputStream(response.getBytes());
ShareXMLParser xmlParser = new ShareXMLParser();
mShares = xmlParser.parseXMLResponse(is);
if (xmlParser.isSuccess()) {
if (mShares != null) {
Log.d(TAG, "Shares: " + mShares.size());
result = new RemoteOperationResult(ResultCode.OK);
ArrayList<Object> sharesObjects = new ArrayList<Object>();
for (OCShare share: mShares) {
sharesObjects.add(share);
}
result.setData(sharesObjects);
}
} else if (xmlParser.isFileNotFound()){
result = new RemoteOperationResult(ResultCode.FILE_NOT_FOUND);
} else {
result = new RemoteOperationResult(false, status, post.getResponseHeaders());
}
} else {
result = new RemoteOperationResult(false, status, post.getResponseHeaders());
}
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Exception while Creating New Share", e);
} finally {
if (post != null) {
post.releaseConnection();
}
}
return result;
}
private boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
}
@@ -0,0 +1,112 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
import android.util.Log;
/**
* Get the data from the server to know shares
*
* @author masensio
*
*/
public class GetRemoteSharesOperation extends RemoteOperation {
private static final String TAG = GetRemoteSharesOperation.class.getSimpleName();
private ArrayList<OCShare> mShares; // List of shares for result
public GetRemoteSharesOperation() {
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
int status = -1;
// Get Method
GetMethod get = null;
// Get the response
try{
get = new GetMethod(client.getBaseUri() + ShareUtils.SHAREAPI_ROUTE);
Log.d(TAG, "URL ------> " + client.getBaseUri() + ShareUtils.SHAREAPI_ROUTE);
status = client.executeMethod(get);
if(isSuccess(status)) {
Log.d(TAG, "Obtain RESPONSE");
String response = get.getResponseBodyAsString();
Log.d(TAG, response);
// Parse xml response --> obtain the response in ShareFiles ArrayList
// convert String into InputStream
InputStream is = new ByteArrayInputStream(response.getBytes());
ShareXMLParser xmlParser = new ShareXMLParser();
mShares = xmlParser.parseXMLResponse(is);
if (mShares != null) {
Log.d(TAG, "Shares: " + mShares.size());
result = new RemoteOperationResult(ResultCode.OK);
ArrayList<Object> sharesObjects = new ArrayList<Object>();
for (OCShare share: mShares) {
sharesObjects.add(share);
}
result.setData(sharesObjects);
}
} else {
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
}
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Exception while getting remote shares ", e);
} finally {
if (get != null) {
get.releaseConnection();
}
}
return result;
}
private boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
}
@@ -0,0 +1,142 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
/**
* Provide a list shares for a specific file.
* The input is the full path of the desired file.
* The output is a list of everyone who has the file shared with them.
*
* @author masensio
*
*/
public class GetSharesForFileRemoteOperation extends RemoteOperation {
private static final String TAG = GetSharesForFileRemoteOperation.class.getSimpleName();
private static final String PARAM_PATH = "path";
private static final String PARAM_RESHARES = "reshares";
private static final String PARAM_SUBFILES = "subfiles";
private ArrayList<OCShare> mShares; // List of shares for result, one share in this case
private String mPath;
private boolean mReshares;
private boolean mSubfiles;
/**
* Constructor
*
* @param path Path to file or folder
* @param reshares If set to false (default), only shares from the current user are returned
* If set to true, all shares from the given file are returned
* @param subfiles If set to false (default), lists only the folder being shared
* If set to true, all shared files within the folder are returned.
*/
public GetSharesForFileRemoteOperation(String path, boolean reshares, boolean subfiles) {
mPath = path;
mReshares = reshares;
mSubfiles = subfiles;
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
int status = -1;
GetMethod get = null;
try {
// Get Method
get = new GetMethod(client.getBaseUri() + ShareUtils.SHAREAPI_ROUTE);
Log.d(TAG, "URL ------> " + client.getBaseUri() + ShareUtils.SHAREAPI_ROUTE);
// Add Parameters to Get Method
get.setQueryString(new NameValuePair[] {
new NameValuePair(PARAM_PATH, mPath),
new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)),
new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles))
});
status = client.executeMethod(get);
if(isSuccess(status)) {
String response = get.getResponseBodyAsString();
Log.d(TAG, "Successful response: " + response);
result = new RemoteOperationResult(ResultCode.OK);
// Parse xml response --> obtain the response in ShareFiles ArrayList
// convert String into InputStream
InputStream is = new ByteArrayInputStream(response.getBytes());
ShareXMLParser xmlParser = new ShareXMLParser();
mShares = xmlParser.parseXMLResponse(is);
if (mShares != null) {
Log.d(TAG, "Shares: " + mShares.size());
result = new RemoteOperationResult(ResultCode.OK);
ArrayList<Object> sharesObjects = new ArrayList<Object>();
for (OCShare share: mShares) {
sharesObjects.add(share);
}
result.setData(sharesObjects);
}
} else {
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
}
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Exception while Creating New Share", e);
} finally {
if (get != null) {
get.releaseConnection();
}
}
return result;
}
private boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
}
@@ -0,0 +1,351 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;
import android.util.Xml;
/**
* Parser for Share API Response: GetSharesForFile Operation
* @author masensio
*
*/
public class GetSharesForFileXMLParser {
private static final String TAG = GetSharesForFileXMLParser.class.getSimpleName();
// No namespaces
private static final String ns = null;
// NODES for XML Parser
private static final String NODE_OCS = "ocs";
private static final String NODE_META = "meta";
private static final String NODE_STATUS = "status";
private static final String NODE_STATUS_CODE = "statuscode";
//private static final String NODE_MESSAGE = "message";
private static final String NODE_DATA = "data";
private static final String NODE_ELEMENT = "element";
private static final String NODE_ID = "id";
private static final String NODE_ITEM_TYPE = "item_type";
private static final String NODE_ITEM_SOURCE = "item_source";
private static final String NODE_PARENT = "parent";
private static final String NODE_SHARE_TYPE = "share_type";
private static final String NODE_SHARE_WITH = "share_with";
private static final String NODE_FILE_SOURCE = "file_source";
private static final String NODE_PATH = "path";
private static final String NODE_PERMISSIONS = "permissions";
private static final String NODE_STIME = "stime";
private static final String NODE_EXPIRATION = "expiration";
private static final String NODE_TOKEN = "token";
private static final String NODE_STORAGE = "storage";
private static final String NODE_MAIL_SEND = "mail_send";
private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_display_name";
private static final String TYPE_FOLDER = "folder";
private String mStatus;
private int mStatusCode;
// Getters and Setters
public String getStatus() {
return mStatus;
}
public void setStatus(String status) {
this.mStatus = status;
}
public int getStatusCode() {
return mStatusCode;
}
public void setStatusCode(int statusCode) {
this.mStatusCode = statusCode;
}
// Constructor
public GetSharesForFileXMLParser() {
// TODO Auto-generated constructor stub
}
/**
* Parse is as response of Share API
* @param is
* @return List of ShareRemoteFiles
* @throws XmlPullParserException
* @throws IOException
*/
public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException, IOException {
try {
// XMLPullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
parser.nextTag();
return readOCS(parser);
} finally {
is.close();
}
}
/**
* Parse OCS node
* @param parser
* @return List of ShareRemoteFiles
* @throws XmlPullParserException
* @throws IOException
*/
private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException, IOException {
ArrayList<OCShare> shares = new ArrayList<OCShare>();
parser.require(XmlPullParser.START_TAG, ns , NODE_OCS);
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// read NODE_META and NODE_DATA
if (name.equalsIgnoreCase(NODE_META)) {
readMeta(parser);
} else if (name.equalsIgnoreCase(NODE_DATA)) {
shares = readData(parser);
} else {
skip(parser);
}
}
return shares;
}
/**
* Parse Meta node
* @param parser
* @throws XmlPullParserException
* @throws IOException
*/
private void readMeta(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, NODE_META);
Log.d(TAG, "---- NODE META ---");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equalsIgnoreCase(NODE_STATUS)) {
setStatus(readNode(parser, NODE_STATUS));
} else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) {
setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE)));
} else {
skip(parser);
}
}
}
/**
* Parse Data node
* @param parser
* @return
* @throws XmlPullParserException
* @throws IOException
*/
private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException, IOException {
ArrayList<OCShare> shares = new ArrayList<OCShare>();
parser.require(XmlPullParser.START_TAG, ns, NODE_DATA);
Log.d(TAG, "---- NODE DATA ---");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equalsIgnoreCase(NODE_ELEMENT)) {
shares.add(readElement(parser));
} else {
skip(parser);
}
}
return shares;
}
/**
* Parse Element node
* @param parser
* @return
* @throws XmlPullParserException
* @throws IOException
*/
private OCShare readElement(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT);
OCShare share = new OCShare();
Log.d(TAG, "---- NODE ELEMENT ---");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equalsIgnoreCase(NODE_ELEMENT)) {
share = readElement(parser);
} else if (name.equalsIgnoreCase(NODE_ID)) {
share.setIdRemoteShared(Integer.parseInt(readNode(parser, NODE_ID)));
} else if (name.equalsIgnoreCase(NODE_ITEM_TYPE)) {
share.setIsFolder(readNode(parser, NODE_ITEM_TYPE).equalsIgnoreCase(TYPE_FOLDER));
} else if (name.equalsIgnoreCase(NODE_ITEM_SOURCE)) {
share.setItemSource(Long.parseLong(readNode(parser, NODE_ITEM_SOURCE)));
} else if (name.equalsIgnoreCase(NODE_PARENT)) {
readNode(parser, NODE_PARENT);
} else if (name.equalsIgnoreCase(NODE_SHARE_TYPE)) {
int value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE));
share.setShareType(ShareType.fromValue(value));
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH)) {
share.setShareWith(readNode(parser, NODE_SHARE_WITH));
} else if (name.equalsIgnoreCase(NODE_FILE_SOURCE)) {
share.setFileSource(Long.parseLong(readNode(parser, NODE_FILE_SOURCE)));
} else if (name.equalsIgnoreCase(NODE_PATH)) {
share.setPath(readNode(parser, NODE_PATH));
} else if (name.equalsIgnoreCase(NODE_PERMISSIONS)) {
share.setPermissions(Integer.parseInt(readNode(parser, NODE_PERMISSIONS)));
} else if (name.equalsIgnoreCase(NODE_STIME)) {
share.setSharedDate(Long.parseLong(readNode(parser, NODE_STIME)));
} else if (name.equalsIgnoreCase(NODE_EXPIRATION)) {
String value = readNode(parser, NODE_EXPIRATION);
if (!value.isEmpty()) {
share.setExpirationDate(Long.parseLong(readNode(parser, NODE_EXPIRATION))); // check if expiration is in long format or date format
}
} else if (name.equalsIgnoreCase(NODE_TOKEN)) {
share.setToken(readNode(parser, NODE_TOKEN));
} else if (name.equalsIgnoreCase(NODE_STORAGE)) {
readNode(parser, NODE_STORAGE);
} else if (name.equalsIgnoreCase(NODE_MAIL_SEND)) {
readNode(parser, NODE_MAIL_SEND);
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) {
share.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME));
} else {
skip(parser);
}
}
return share;
}
/**
* Parse a node, to obtain its text. Needs readText method
* @param parser
* @param node
* @return Text of the node
* @throws XmlPullParserException
* @throws IOException
*/
private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, IOException{
parser.require(XmlPullParser.START_TAG, ns, node);
String value = readText(parser);
Log.d(TAG, "node= " + node + ", value= " + value);
parser.require(XmlPullParser.END_TAG, ns, node);
return value;
}
/**
* Read the text from a node
* @param parser
* @return Text of the node
* @throws IOException
* @throws XmlPullParserException
*/
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
/**
* Skip tags in parser procedure
* @param parser
* @throws XmlPullParserException
* @throws IOException
*/
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
}
@@ -0,0 +1,295 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
import java.io.Serializable;
import com.owncloud.android.lib.resources.files.FileUtils;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
/**
* Contains the data of a Share from the Share API
*
* @author masensio
*
*/
public class OCShare implements Parcelable, Serializable {
/** Generated - should be refreshed every time the class changes!! */
private static final long serialVersionUID = 4124975224281327921L;
private static final String TAG = OCShare.class.getSimpleName();
private long mId;
private long mFileSource;
private long mItemSource;
private ShareType mShareType;
private String mShareWith;
private String mPath;
private int mPermissions;
private long mSharedDate;
private long mExpirationDate;
private String mToken;
private String mSharedWithDisplayName;
private boolean mIsFolder;
private long mUserId;
private long mIdRemoteShared;
private String mShareLink;
public OCShare() {
super();
resetData();
}
public OCShare(String path) {
resetData();
if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) {
Log.e(TAG, "Trying to create a OCShare with a non valid path");
throw new IllegalArgumentException("Trying to create a OCShare with a non valid path: " + path);
}
mPath = path;
}
/**
* Used internally. Reset all file properties
*/
private void resetData() {
mId = -1;
mFileSource = 0;
mItemSource = 0;
mShareType = ShareType.NO_SHARED;
mShareWith = null;
mPath = null;
mPermissions = -1;
mSharedDate = 0;
mExpirationDate = 0;
mToken = null;
mSharedWithDisplayName = null;
mIsFolder = false;
mUserId = -1;
mIdRemoteShared = -1;
mShareLink = null;
}
/// Getters and Setters
public long getId() {
return mId;
}
public void setId(long id){
mId = id;
}
public long getFileSource() {
return mFileSource;
}
public void setFileSource(long fileSource) {
this.mFileSource = fileSource;
}
public long getItemSource() {
return mItemSource;
}
public void setItemSource(long itemSource) {
this.mItemSource = itemSource;
}
public ShareType getShareType() {
return mShareType;
}
public void setShareType(ShareType shareType) {
this.mShareType = shareType;
}
public String getShareWith() {
return mShareWith;
}
public void setShareWith(String shareWith) {
this.mShareWith = shareWith;
}
public String getPath() {
return mPath;
}
public void setPath(String path) {
this.mPath = path;
}
public int getPermissions() {
return mPermissions;
}
public void setPermissions(int permissions) {
this.mPermissions = permissions;
}
public long getSharedDate() {
return mSharedDate;
}
public void setSharedDate(long sharedDate) {
this.mSharedDate = sharedDate;
}
public long getExpirationDate() {
return mExpirationDate;
}
public void setExpirationDate(long expirationDate) {
this.mExpirationDate = expirationDate;
}
public String getToken() {
return mToken;
}
public void setToken(String token) {
this.mToken = token;
}
public String getSharedWithDisplayName() {
return mSharedWithDisplayName;
}
public void setSharedWithDisplayName(String sharedWithDisplayName) {
this.mSharedWithDisplayName = sharedWithDisplayName;
}
public boolean isFolder() {
return mIsFolder;
}
public void setIsFolder(boolean isFolder) {
this.mIsFolder = isFolder;
}
public long getUserId() {
return mUserId;
}
public void setUserId(long userId) {
this.mUserId = userId;
}
public long getIdRemoteShared() {
return mIdRemoteShared;
}
public void setIdRemoteShared(long idRemoteShared) {
this.mIdRemoteShared = idRemoteShared;
}
public String getShareLink() {
return this.mShareLink;
}
public void setShareLink(String shareLink) {
this.mShareLink = shareLink;
}
/**
* Parcelable Methods
*/
public static final Parcelable.Creator<OCShare> CREATOR = new Parcelable.Creator<OCShare>() {
@Override
public OCShare createFromParcel(Parcel source) {
return new OCShare(source);
}
@Override
public OCShare[] newArray(int size) {
return new OCShare[size];
}
};
/**
* Reconstruct from parcel
*
* @param source The source parcel
*/
protected OCShare(Parcel source) {
readFromParcel(source);
}
public void readFromParcel(Parcel source) {
mId = source.readLong();
mFileSource = source.readLong();
mItemSource = source.readLong();
try {
mShareType = ShareType.valueOf(source.readString());
} catch (IllegalArgumentException x) {
mShareType = ShareType.NO_SHARED;
}
mShareWith = source.readString();
mPath = source.readString();
mPermissions = source.readInt();
mSharedDate = source.readLong();
mExpirationDate = source.readLong();
mToken = source.readString();
mSharedWithDisplayName = source.readString();
mIsFolder = source.readInt() == 0;
mUserId = source.readLong();
mIdRemoteShared = source.readLong();
mShareLink = source.readString();
}
@Override
public int describeContents() {
return this.hashCode();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mId);
dest.writeLong(mFileSource);
dest.writeLong(mItemSource);
dest.writeString((mShareType == null) ? "" : mShareType.name());
dest.writeString(mShareWith);
dest.writeString(mPath);
dest.writeInt(mPermissions);
dest.writeLong(mSharedDate);
dest.writeLong(mExpirationDate);
dest.writeString(mToken);
dest.writeString(mSharedWithDisplayName);
dest.writeInt(mIsFolder ? 1 : 0);
dest.writeLong(mUserId);
dest.writeLong(mIdRemoteShared);
dest.writeString(mShareLink);
}
}
@@ -0,0 +1,78 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
/**
* Enum for Share Type, with values:
* -1 - No shared
* 0 - Shared by user
* 1 - Shared by group
* 3 - Shared by public link
* 4 - Shared by e-mail
* 5 - Shared by contact
*
* @author masensio
*
*/
public enum ShareType {
NO_SHARED (-1),
USER (0),
GROUP (1),
PUBLIC_LINK (3),
EMAIL (4),
CONTACT (5);
private int value;
private ShareType(int value)
{
this.value = value;
}
public int getValue() {
return value;
}
public static ShareType fromValue(int value)
{
switch (value)
{
case -1:
return NO_SHARED;
case 0:
return USER;
case 1:
return GROUP;
case 3:
return PUBLIC_LINK;
case 4:
return EMAIL;
case 5:
return CONTACT;
}
return null;
}
};
@@ -0,0 +1,39 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
/**
* Contains Constants for Share Operation
*
* @author masensio
*
*/
public class ShareUtils {
// OCS Route
public static final String SHAREAPI_ROUTE ="/ocs/v1.php/apps/files_sharing/api/v1/shares";
}
@@ -0,0 +1,391 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.shares;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Log;
import android.util.Xml;
import com.owncloud.android.lib.resources.files.FileUtils;
/**
* Parser for Share API Response
* @author masensio
*
*/
public class ShareXMLParser {
private static final String TAG = ShareXMLParser.class.getSimpleName();
// No namespaces
private static final String ns = null;
// NODES for XML Parser
private static final String NODE_OCS = "ocs";
private static final String NODE_META = "meta";
private static final String NODE_STATUS = "status";
private static final String NODE_STATUS_CODE = "statuscode";
//private static final String NODE_MESSAGE = "message";
private static final String NODE_DATA = "data";
private static final String NODE_ELEMENT = "element";
private static final String NODE_ID = "id";
private static final String NODE_ITEM_TYPE = "item_type";
private static final String NODE_ITEM_SOURCE = "item_source";
private static final String NODE_PARENT = "parent";
private static final String NODE_SHARE_TYPE = "share_type";
private static final String NODE_SHARE_WITH = "share_with";
private static final String NODE_FILE_SOURCE = "file_source";
private static final String NODE_PATH = "path";
private static final String NODE_PERMISSIONS = "permissions";
private static final String NODE_STIME = "stime";
private static final String NODE_EXPIRATION = "expiration";
private static final String NODE_TOKEN = "token";
private static final String NODE_STORAGE = "storage";
private static final String NODE_MAIL_SEND = "mail_send";
private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_display_name";
private static final String NODE_URL = "url";
private static final String TYPE_FOLDER = "folder";
private static final int SUCCESS = 100;
private static final int FAILURE = 403;
private static final int FILE_NOT_FOUND = 404;
private String mStatus;
private int mStatusCode;
// Getters and Setters
public String getStatus() {
return mStatus;
}
public void setStatus(String status) {
this.mStatus = status;
}
public int getStatusCode() {
return mStatusCode;
}
public void setStatusCode(int statusCode) {
this.mStatusCode = statusCode;
}
// Constructor
public ShareXMLParser() {
mStatusCode = 100;
}
public boolean isSuccess() {
return mStatusCode == SUCCESS;
}
public boolean isFailure() {
return mStatusCode == FAILURE;
}
public boolean isFileNotFound() {
return mStatusCode == FILE_NOT_FOUND;
}
/**
* Parse is as response of Share API
* @param is
* @return List of ShareRemoteFiles
* @throws XmlPullParserException
* @throws IOException
*/
public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException, IOException {
try {
// XMLPullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
parser.nextTag();
return readOCS(parser);
} finally {
is.close();
}
}
/**
* Parse OCS node
* @param parser
* @return List of ShareRemoteFiles
* @throws XmlPullParserException
* @throws IOException
*/
private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException, IOException {
ArrayList<OCShare> shares = new ArrayList<OCShare>();
parser.require(XmlPullParser.START_TAG, ns , NODE_OCS);
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// read NODE_META and NODE_DATA
if (name.equalsIgnoreCase(NODE_META)) {
readMeta(parser);
} else if (name.equalsIgnoreCase(NODE_DATA)) {
shares = readData(parser);
} else {
skip(parser);
}
}
return shares;
}
/**
* Parse Meta node
* @param parser
* @throws XmlPullParserException
* @throws IOException
*/
private void readMeta(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, NODE_META);
Log.d(TAG, "---- NODE META ---");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equalsIgnoreCase(NODE_STATUS)) {
setStatus(readNode(parser, NODE_STATUS));
} else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) {
setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE)));
} else {
skip(parser);
}
}
}
/**
* Parse Data node
* @param parser
* @return
* @throws XmlPullParserException
* @throws IOException
*/
private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException, IOException {
ArrayList<OCShare> shares = new ArrayList<OCShare>();
OCShare share = null;
parser.require(XmlPullParser.START_TAG, ns, NODE_DATA);
Log.d(TAG, "---- NODE DATA ---");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equalsIgnoreCase(NODE_ELEMENT)) {
shares.add(readElement(parser));
} else if (name.equalsIgnoreCase(NODE_ID)) {// Parse Create XML Response
share = new OCShare();
String value = readNode(parser, NODE_ID);
share.setIdRemoteShared(Integer.parseInt(value));
} else if (name.equalsIgnoreCase(NODE_URL)) {
share.setShareType(ShareType.PUBLIC_LINK);
String value = readNode(parser, NODE_URL);
share.setShareLink(value);
} else if (name.equalsIgnoreCase(NODE_TOKEN)) {
share.setToken(readNode(parser, NODE_TOKEN));
} else {
skip(parser);
}
}
if (share != null) {
shares.add(share);
}
return shares;
}
/**
* Parse Element node
* @param parser
* @return
* @throws XmlPullParserException
* @throws IOException
*/
private OCShare readElement(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT);
OCShare share = new OCShare();
Log.d(TAG, "---- NODE ELEMENT ---");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equalsIgnoreCase(NODE_ID)) {
share.setIdRemoteShared(Integer.parseInt(readNode(parser, NODE_ID)));
} else if (name.equalsIgnoreCase(NODE_ITEM_TYPE)) {
share.setIsFolder(readNode(parser, NODE_ITEM_TYPE).equalsIgnoreCase(TYPE_FOLDER));
fixPathForFolder(share);
} else if (name.equalsIgnoreCase(NODE_ITEM_SOURCE)) {
share.setItemSource(Long.parseLong(readNode(parser, NODE_ITEM_SOURCE)));
} else if (name.equalsIgnoreCase(NODE_PARENT)) {
readNode(parser, NODE_PARENT);
} else if (name.equalsIgnoreCase(NODE_SHARE_TYPE)) {
int value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE));
share.setShareType(ShareType.fromValue(value));
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH)) {
share.setShareWith(readNode(parser, NODE_SHARE_WITH));
} else if (name.equalsIgnoreCase(NODE_FILE_SOURCE)) {
share.setFileSource(Long.parseLong(readNode(parser, NODE_FILE_SOURCE)));
} else if (name.equalsIgnoreCase(NODE_PATH)) {
share.setPath(readNode(parser, NODE_PATH));
fixPathForFolder(share);
} else if (name.equalsIgnoreCase(NODE_PERMISSIONS)) {
share.setPermissions(Integer.parseInt(readNode(parser, NODE_PERMISSIONS)));
} else if (name.equalsIgnoreCase(NODE_STIME)) {
share.setSharedDate(Long.parseLong(readNode(parser, NODE_STIME)));
} else if (name.equalsIgnoreCase(NODE_EXPIRATION)) {
String value = readNode(parser, NODE_EXPIRATION);
if (!value.isEmpty()) {
share.setExpirationDate(Long.parseLong(readNode(parser, NODE_EXPIRATION))); // check if expiration is in long format or date format
}
} else if (name.equalsIgnoreCase(NODE_TOKEN)) {
share.setToken(readNode(parser, NODE_TOKEN));
} else if (name.equalsIgnoreCase(NODE_STORAGE)) {
readNode(parser, NODE_STORAGE);
} else if (name.equalsIgnoreCase(NODE_MAIL_SEND)) {
readNode(parser, NODE_MAIL_SEND);
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) {
share.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME));
} else {
skip(parser);
}
}
return share;
}
private void fixPathForFolder(OCShare share) {
if (share.isFolder() && share.getPath() != null && share.getPath().length() > 0 && !share.getPath().endsWith(FileUtils.PATH_SEPARATOR)) {
share.setPath(share.getPath() + FileUtils.PATH_SEPARATOR);
}
}
/**
* Parse a node, to obtain its text. Needs readText method
* @param parser
* @param node
* @return Text of the node
* @throws XmlPullParserException
* @throws IOException
*/
private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, IOException{
parser.require(XmlPullParser.START_TAG, ns, node);
String value = readText(parser);
Log.d(TAG, "node= " + node + ", value= " + value);
parser.require(XmlPullParser.END_TAG, ns, node);
return value;
}
/**
* Read the text from a node
* @param parser
* @return Text of the node
* @throws IOException
* @throws XmlPullParserException
*/
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
/**
* Skip tags in parser procedure
* @param parser
* @throws XmlPullParserException
* @throws IOException
*/
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
}
@@ -0,0 +1,172 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.status;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.json.JSONException;
import org.json.JSONObject;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.Log;
/**
* Checks if the server is valid and if the server supports the Share API
*
* @author David A. Velasco
* @author masensio
*
*/
public class OwnCloudServerCheckOperation extends RemoteOperation {
/** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs. */
public static final int TRY_CONNECTION_TIMEOUT = 5000;
private static final String TAG = OwnCloudServerCheckOperation.class.getSimpleName();
private static final String OCVERSION_SHARED_SUPPORTED = "5.0.13";
private static final String NODE_INSTALLED = "installed";
private static final String NODE_VERSION = "version";
private static final String NODE_VERSIONSTRING = "versionstring";
private String mUrl;
private RemoteOperationResult mLatestResult;
private Context mContext;
private OwnCloudVersion mOCVersion;
private OwnCloudVersion mOCVersionString;
public OwnCloudServerCheckOperation(String url, Context context) {
mUrl = url;
mContext = context;
mOCVersion = null;
mOCVersionString = null;
}
public OwnCloudVersion getDiscoveredVersion() {
return mOCVersion;
}
public boolean isSharedSupported() {
OwnCloudVersion shareServer = new OwnCloudVersion(OCVERSION_SHARED_SUPPORTED);
if (mOCVersionString != null) {
return mOCVersionString.compareTo(shareServer) >= 0;
}
return false;
}
private boolean tryConnection(OwnCloudClient wc, String urlSt) {
boolean retval = false;
GetMethod get = null;
try {
get = new GetMethod(urlSt);
int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
String response = get.getResponseBodyAsString();
if (status == HttpStatus.SC_OK) {
JSONObject json = new JSONObject(response);
if (!json.getBoolean(NODE_INSTALLED)) {
mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
} else {
mOCVersion = new OwnCloudVersion(json.getString(NODE_VERSION));
mOCVersionString = new OwnCloudVersion(json.getString(NODE_VERSIONSTRING), true);
if (!mOCVersion.isVersionValid()) {
mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.BAD_OC_VERSION);
} else {
mLatestResult = new RemoteOperationResult(urlSt.startsWith("https://") ?
RemoteOperationResult.ResultCode.OK_SSL :
RemoteOperationResult.ResultCode.OK_NO_SSL
);
retval = true;
}
}
} else {
mLatestResult = new RemoteOperationResult(false, status, get.getResponseHeaders());
}
} catch (JSONException e) {
mLatestResult = new RemoteOperationResult(RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
} catch (Exception e) {
mLatestResult = new RemoteOperationResult(e);
} finally {
if (get != null)
get.releaseConnection();
}
if (mLatestResult.isSuccess()) {
Log.i(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
} else if (mLatestResult.getException() != null) {
Log.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage(), mLatestResult.getException());
} else {
Log.e(TAG, "Connection check at " + urlSt + ": " + mLatestResult.getLogMessage());
}
return retval;
}
private boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) mContext
.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm != null && cm.getActiveNetworkInfo() != null
&& cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
if (!isOnline()) {
return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
}
if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
tryConnection(client, mUrl + AccountUtils.STATUS_PATH);
} else {
client.setWebdavUri(Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH));
boolean httpsSuccess = tryConnection(client, "https://" + mUrl + AccountUtils.STATUS_PATH);
if (!httpsSuccess && !mLatestResult.isSslRecoverableException()) {
Log.d(TAG, "establishing secure connection failed, trying non secure connection");
client.setWebdavUri(Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH));
tryConnection(client, "http://" + mUrl + AccountUtils.STATUS_PATH);
}
}
return mLatestResult;
}
}
@@ -0,0 +1,125 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
* Copyright (C) 2012 Bartek Przybylski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.status;
public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
public static final OwnCloudVersion owncloud_v1 = new OwnCloudVersion(
0x010000);
public static final OwnCloudVersion owncloud_v2 = new OwnCloudVersion(
0x020000);
public static final OwnCloudVersion owncloud_v3 = new OwnCloudVersion(
0x030000);
public static final OwnCloudVersion owncloud_v4 = new OwnCloudVersion(
0x040000);
public static final OwnCloudVersion owncloud_v4_5 = new OwnCloudVersion(
0x040500);
// format is in version
// 0xAABBCC
// for version AA.BB.CC
// ie version 2.0.3 will be stored as 0x030003
private int mVersion;
private boolean mIsValid;
public OwnCloudVersion(int version) {
mVersion = version;
mIsValid = true;
}
public OwnCloudVersion(String version) {
mVersion = 0;
mIsValid = false;
parseVersionString(version);
}
public OwnCloudVersion(String versionstring, boolean isVersionString) {
mVersion = 0;
mIsValid = false;
if (isVersionString) {
parseVersionString(versionstring);
} else {
parseVersion(versionstring);
}
}
public String toString() {
return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "."
+ ((mVersion) % 256);
}
public boolean isVersionValid() {
return mIsValid;
}
@Override
public int compareTo(OwnCloudVersion another) {
return another.mVersion == mVersion ? 0
: another.mVersion < mVersion ? 1 : -1;
}
private void parseVersion(String version) {
try {
String[] nums = version.split("\\.");
if (nums.length > 0) {
mVersion += Integer.parseInt(nums[0]);
}
mVersion = mVersion << 8;
if (nums.length > 1) {
mVersion += Integer.parseInt(nums[1]);
}
mVersion = mVersion << 8;
if (nums.length > 2) {
mVersion += Integer.parseInt(nums[2]);
}
mIsValid = true;
} catch (Exception e) {
mIsValid = false;
}
}
private void parseVersionString(String versionstring) {
try {
versionstring = versionstring.replaceAll("[^\\d.]", "");
String[] nums = versionstring.split("\\.");
if (nums.length > 0) {
mVersion += Integer.parseInt(nums[0]);
}
mVersion = mVersion << 8;
if (nums.length > 1) {
mVersion += Integer.parseInt(nums[1]);
}
mVersion = mVersion << 8;
if (nums.length > 2) {
mVersion += Integer.parseInt(nums[2]);
}
mIsValid = true;
} catch (Exception e) {
mIsValid = false;
}
}
}
@@ -0,0 +1,133 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.users;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import org.json.JSONObject;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
/**
* @author masensio
*
* Get the UserName for a SAML connection, from a JSON with the format:
* id
* display-name
* email
*/
public class GetUserNameRemoteOperation extends RemoteOperation {
private static final String TAG = GetUserNameRemoteOperation.class.getSimpleName();
// HEADER
private static final String HEADER_OCS_API = "OCS-APIREQUEST";
private static final String HEADER_OCS_API_VALUE = "true";
// OCS Route
private static final String OCS_ROUTE ="/index.php/ocs/cloud/user?format=json";
// JSON Node names
private static final String NODE_OCS = "ocs";
private static final String NODE_DATA = "data";
private static final String NODE_ID = "id";
private static final String NODE_DISPLAY_NAME= "display-name";
private static final String NODE_EMAIL= "email";
private String mUserName;
public String getUserName() {
return mUserName;
}
public GetUserNameRemoteOperation() {
}
@Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
int status = -1;
GetMethod get = null;
//Get the user
try {
//GetMethod get = new GetMethod(client.getWebdavUri() + OCS_ROUTE);
get = new GetMethod(client.getBaseUri() + OCS_ROUTE);
Log.e(TAG, "Getting OC user information from " + client.getBaseUri() + OCS_ROUTE);
Log.e(TAG, "Getting OC user information from " + client.getWebdavUri() + OCS_ROUTE);
// Add the Header
get.addRequestHeader(HEADER_OCS_API, HEADER_OCS_API_VALUE);
status = client.executeMethod(get);
if(isSuccess(status)) {
String response = get.getResponseBodyAsString();
Log.d(TAG, "Successful response: " + response);
// Parse the response
JSONObject respJSON = new JSONObject(response);
JSONObject respOCS = respJSON.getJSONObject(NODE_OCS);
JSONObject respData = respOCS.getJSONObject(NODE_DATA);
String id = respData.getString(NODE_ID);
String displayName = respData.getString(NODE_DISPLAY_NAME);
String email = respData.getString(NODE_EMAIL);
// Result
result = new RemoteOperationResult(true, status, get.getResponseHeaders());
mUserName = displayName;
Log.d(TAG, "*** Parsed user information: " + id + " - " + displayName + " - " + email);
} else {
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
String response = get.getResponseBodyAsString();
Log.e(TAG, "Failed response while getting user information ");
if (response != null) {
Log.e(TAG, "*** status code: " + status + " ; response message: " + response);
} else {
Log.e(TAG, "*** status code: " + status);
}
}
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log.e(TAG, "Exception while getting OC user information", e);
} finally {
get.releaseConnection();
}
return result;
}
private boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
}