1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Merge remote-tracking branch 'origin/develop' into bug_null_result_in_GetUserNameRemoteOperation_when_unsucessful

This commit is contained in:
David A. Velasco 2014-01-29 13:01:23 +01:00
commit afb4ae1c2e
23 changed files with 1136 additions and 52 deletions

View File

@ -28,6 +28,7 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -212,7 +213,10 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) { private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) {
mFilesAdapter.clear(); mFilesAdapter.clear();
List<RemoteFile> files = result.getData(); List<RemoteFile> files = new ArrayList<RemoteFile>();
for(Object obj: result.getData()) {
files.add((RemoteFile) obj);
}
if (files != null) { if (files != null) {
Iterator<RemoteFile> it = files.iterator(); Iterator<RemoteFile> it = files.iterator();
while (it.hasNext()) { while (it.hasNext()) {

View File

@ -92,6 +92,23 @@ public class AccountUtils {
return baseurl + webdavpath; return baseurl + webdavpath;
} }
/**
* Extracts url server from the account
* @param context
* @param account
* @return url server or null on failure
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
*/
public static String constructBasicURLForAccount(Context context, Account account) throws AccountNotFoundException {
AccountManager ama = AccountManager.get(context);
String baseurl = ama.getUserData(account, OwnCloudAccount.Constants.KEY_OC_BASE_URL);
if (baseurl == null )
throw new AccountNotFoundException(account, "Account not found", null);
return baseurl;
}
public static class AccountNotFoundException extends AccountsException { public static class AccountNotFoundException extends AccountsException {

View File

@ -65,6 +65,10 @@ public class OwnCloudAccount extends Account {
* Flag signaling if the ownCloud server can be accessed with session cookies from SAML-based web single-sign-on. * Flag signaling if the ownCloud server can be accessed with session cookies from SAML-based web single-sign-on.
*/ */
public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso"; public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso";
/**
* Flag signaling if the ownCloud server supports Share API"
*/
public static final String KEY_SUPPORTS_SHARE_API = "oc_supports_share_api";
} }
private String mAuthTokenType; private String mAuthTokenType;

View File

@ -57,6 +57,7 @@ public class OwnCloudClient extends HttpClient {
private static final int MAX_REDIRECTIONS_COUNT = 3; private static final int MAX_REDIRECTIONS_COUNT = 3;
private Uri mUri; private Uri mUri;
private Uri mWebdavUri;
private Credentials mCredentials; private Credentials mCredentials;
private boolean mFollowRedirects; private boolean mFollowRedirects;
private String mSsoSessionCookie; private String mSsoSessionCookie;
@ -117,7 +118,7 @@ public class OwnCloudClient extends HttpClient {
* @throws Exception When the existence could not be determined * @throws Exception When the existence could not be determined
*/ */
public boolean existsFile(String path) throws IOException, HttpException { public boolean existsFile(String path) throws IOException, HttpException {
HeadMethod head = new HeadMethod(mUri.toString() + WebdavUtils.encodePath(path)); HeadMethod head = new HeadMethod(mWebdavUri.toString() + WebdavUtils.encodePath(path));
try { try {
int status = executeMethod(head); int status = executeMethod(head);
Log.d(TAG, "HEAD to " + path + " finished with HTTP status " + status + ((status != HttpStatus.SC_OK)?"(FAIL)":"")); Log.d(TAG, "HEAD to " + path + " finished with HTTP status " + status + ((status != HttpStatus.SC_OK)?"(FAIL)":""));
@ -224,6 +225,18 @@ public class OwnCloudClient extends HttpClient {
getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout); getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout);
} }
/**
* Sets the Webdav URI for the helper methods that receive paths as parameters, instead of full URLs
* @param uri
*/
public void setWebdavUri(Uri uri) {
mWebdavUri = uri;
}
public Uri getWebdavUri() {
return mWebdavUri;
}
/** /**
* Sets the base URI for the helper methods that receive paths as parameters, instead of full URLs * Sets the base URI for the helper methods that receive paths as parameters, instead of full URLs
* @param uri * @param uri

View File

@ -70,11 +70,14 @@ public class OwnCloudClientFactory {
public static OwnCloudClient createOwnCloudClient (Account account, Context appContext) throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException { public static OwnCloudClient createOwnCloudClient (Account account, Context appContext) throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException {
//Log_OC.d(TAG, "Creating OwnCloudClient associated to " + account.name); //Log_OC.d(TAG, "Creating OwnCloudClient associated to " + account.name);
Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account)); Uri webdavUri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account));
Uri uri = Uri.parse(AccountUtils.constructBasicURLForAccount(appContext, account));
AccountManager am = AccountManager.get(appContext); AccountManager am = AccountManager.get(appContext);
boolean isOauth2 = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_OAUTH2) != null; // TODO avoid calling to getUserData here boolean isOauth2 = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_OAUTH2) != null; // TODO avoid calling to getUserData here
boolean isSamlSso = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null; boolean isSamlSso = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
OwnCloudClient client = createOwnCloudClient(uri, appContext, !isSamlSso); OwnCloudClient client = createOwnCloudClient(webdavUri, appContext, !isSamlSso);
client.setBaseUri(uri);
if (isOauth2) { if (isOauth2) {
String accessToken = am.blockingGetAuthToken(account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), false); String accessToken = am.blockingGetAuthToken(account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), false);
client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token client.setBearerCredentials(accessToken); // TODO not assume that the access token is a bearer token
@ -95,11 +98,13 @@ public class OwnCloudClientFactory {
public static OwnCloudClient createOwnCloudClient (Account account, Context appContext, Activity currentActivity) throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException { public static OwnCloudClient createOwnCloudClient (Account account, Context appContext, Activity currentActivity) throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException {
Uri uri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account)); Uri webdavUri = Uri.parse(AccountUtils.constructFullURLForAccount(appContext, account));
Uri uri = Uri.parse(AccountUtils.constructBasicURLForAccount(appContext, account));
AccountManager am = AccountManager.get(appContext); AccountManager am = AccountManager.get(appContext);
boolean isOauth2 = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_OAUTH2) != null; // TODO avoid calling to getUserData here boolean isOauth2 = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_OAUTH2) != null; // TODO avoid calling to getUserData here
boolean isSamlSso = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null; boolean isSamlSso = am.getUserData(account, OwnCloudAccount.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
OwnCloudClient client = createOwnCloudClient(uri, appContext, !isSamlSso); OwnCloudClient client = createOwnCloudClient(webdavUri, appContext, !isSamlSso);
client.setBaseUri(uri);
if (isOauth2) { // TODO avoid a call to getUserData here if (isOauth2) { // TODO avoid a call to getUserData here
AccountManagerFuture<Bundle> future = am.getAuthToken(account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), null, currentActivity, null, null); AccountManagerFuture<Bundle> future = am.getAuthToken(account, AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), null, currentActivity, null, null);
@ -148,7 +153,7 @@ public class OwnCloudClientFactory {
OwnCloudClient client = new OwnCloudClient(NetworkUtils.getMultiThreadedConnManager()); OwnCloudClient client = new OwnCloudClient(NetworkUtils.getMultiThreadedConnManager());
client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT); client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
client.setBaseUri(uri); client.setWebdavUri(uri);
client.setFollowRedirects(followRedirects); client.setFollowRedirects(followRedirects);
return client; return client;

View File

@ -0,0 +1,278 @@
/* 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.operations.common;
import com.owncloud.android.lib.utils.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{
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 mIsDirectory;
private long mUserId;
private long mIdRemoteShared;
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;
mIsDirectory = false;
mUserId = -1;
mIdRemoteShared = -1;
}
/// 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 isDirectory() {
return mIsDirectory;
}
public void setIsDirectory(boolean isDirectory) {
this.mIsDirectory = isDirectory;
}
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;
}
/**
* 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();
mIsDirectory = source.readInt() == 0;
mUserId = source.readLong();
mIdRemoteShared = source.readLong();
}
@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(mIsDirectory ? 1 : 0);
dest.writeLong(mUserId);
dest.writeLong(mIdRemoteShared);
}
}

View File

@ -101,6 +101,10 @@ public class RemoteFile implements Parcelable, Serializable {
public void setEtag(String etag) { public void setEtag(String etag) {
this.mEtag = etag; this.mEtag = etag;
} }
public RemoteFile() {
resetData();
}
/** /**
* Create new {@link RemoteFile} with given path. * Create new {@link RemoteFile} with given path.
@ -159,7 +163,11 @@ public class RemoteFile implements Parcelable, Serializable {
* *
* @param source The source parcel * @param source The source parcel
*/ */
private RemoteFile(Parcel source) { protected RemoteFile(Parcel source) {
readFromParcel(source);
}
public void readFromParcel (Parcel source) {
mRemotePath = source.readString(); mRemotePath = source.readString();
mMimeType = source.readString(); mMimeType = source.readString();
mLength = source.readLong(); mLength = source.readLong();

View File

@ -106,12 +106,12 @@ public class RemoteOperationResult implements Serializable {
private ResultCode mCode = ResultCode.UNKNOWN_ERROR; private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
private String mRedirectedLocation; private String mRedirectedLocation;
private ArrayList<RemoteFile> mFiles; private ArrayList<Object> mData;
public RemoteOperationResult(ResultCode code) { public RemoteOperationResult(ResultCode code) {
mCode = code; mCode = code;
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL); mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL);
mFiles = null; mData = null;
} }
private RemoteOperationResult(boolean success, int httpCode) { private RemoteOperationResult(boolean success, int httpCode) {
@ -207,12 +207,12 @@ public class RemoteOperationResult implements Serializable {
} }
public void setData(ArrayList<RemoteFile> files){ public void setData(ArrayList<Object> files){
mFiles = files; mData = files;
} }
public ArrayList<RemoteFile> getData(){ public ArrayList<Object> getData(){
return mFiles; return mData;
} }
public boolean isSuccess() { public boolean isSuccess() {

View File

@ -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.operations.common;
/**
* 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;
}
};

View File

@ -70,7 +70,7 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation
} }
long offset = 0; long offset = 0;
String uriPrefix = client.getBaseUri() + WebdavUtils.encodePath(mRemotePath) + "-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ; 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); long chunkCount = (long) Math.ceil((double)file.length() / CHUNK_SIZE);
for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) { for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
if (mPutMethod != null) { if (mPutMethod != null) {

View File

@ -80,7 +80,7 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
boolean noInvalidChars = FileUtils.isValidPath(mRemotePath); boolean noInvalidChars = FileUtils.isValidPath(mRemotePath);
if (noInvalidChars) { if (noInvalidChars) {
try { try {
mkcol = new MkColMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT); int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
if (!mkcol.succeeded() && mkcol.getStatusCode() == HttpStatus.SC_CONFLICT && mCreateFullPath) { if (!mkcol.succeeded() && mkcol.getStatusCode() == HttpStatus.SC_CONFLICT && mCreateFullPath) {
result = createParentFolder(FileUtils.getParentPath(mRemotePath), client); result = createParentFolder(FileUtils.getParentPath(mRemotePath), client);

View File

@ -98,7 +98,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
protected int downloadFile(OwnCloudClient client, File targetFile) throws HttpException, IOException, OperationCancelledException { protected int downloadFile(OwnCloudClient client, File targetFile) throws HttpException, IOException, OperationCancelledException {
int status = -1; int status = -1;
boolean savedFile = false; boolean savedFile = false;
mGet = new GetMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); mGet = new GetMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
Iterator<OnDatatransferProgressListener> it = null; Iterator<OnDatatransferProgressListener> it = null;
FileOutputStream fos = null; FileOutputStream fos = null;

View File

@ -75,16 +75,16 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
RemoteOperationResult result = null; RemoteOperationResult result = null;
HeadMethod head = null; HeadMethod head = null;
try { try {
head = new HeadMethod(client.getBaseUri() + WebdavUtils.encodePath(mPath)); head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath));
int status = client.executeMethod(head, TIMEOUT, TIMEOUT); int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
client.exhaustResponse(head.getResponseBodyAsStream()); client.exhaustResponse(head.getResponseBodyAsStream());
boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent); boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) || (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
result = new RemoteOperationResult(success, status, head.getResponseHeaders()); result = new RemoteOperationResult(success, status, head.getResponseHeaders());
Log.d(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + "finished with HTTP status " + status + (!success?"(FAIL)":"")); 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) { } catch (Exception e) {
result = new RemoteOperationResult(e); result = new RemoteOperationResult(e);
Log.e(TAG, "Existence check for " + client.getBaseUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException()); Log.e(TAG, "Existence check for " + client.getWebdavUri() + WebdavUtils.encodePath(mPath) + " targeting for " + (mSuccessIfAbsent ? " absence " : " existence ") + ": " + result.getLogMessage(), result.getException());
} finally { } finally {
if (head != null) if (head != null)

View File

@ -0,0 +1,119 @@
/* 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.operations.remote;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import org.xmlpull.v1.XmlPullParserException;
import com.owncloud.android.lib.network.OwnCloudClient;
import com.owncloud.android.lib.operations.common.RemoteOperation;
import com.owncloud.android.lib.operations.common.RemoteOperationResult;
import com.owncloud.android.lib.operations.common.RemoteOperationResult.ResultCode;
import com.owncloud.android.lib.operations.common.OCShare;
import com.owncloud.android.lib.utils.ShareXMLParser;
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();
// OCS Route
private static final String SHAREAPI_ROUTE ="/ocs/v1.php/apps/files_sharing/api/v1/shares";
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 = new GetMethod(client.getBaseUri() + SHAREAPI_ROUTE);
Log.d(TAG, "URL ------> " + client.getBaseUri() + SHAREAPI_ROUTE);
// Get the response
try{
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);
}
}
} catch (HttpException e) {
result = new RemoteOperationResult(e);
e.printStackTrace();
} catch (IOException e) {
result = new RemoteOperationResult(e);
e.printStackTrace();
} catch (XmlPullParserException e) {
result = new RemoteOperationResult(e);
e.printStackTrace();
} finally {
get.releaseConnection();
}
return result;
}
private boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
}

View File

@ -1,28 +1,31 @@
/* ownCloud Android Library is available under MIT license
/* ownCloud Android client application * Copyright (C) 2014 ownCloud (http://www.owncloud.org/)
* Copyright (C) 2012-2013 ownCloud Inc. *
* * Permission is hereby granted, free of charge, to any person obtaining a copy
* This program is free software: you can redistribute it and/or modify * of this software and associated documentation files (the "Software"), to deal
* it under the terms of the GNU General Public License version 2, * in the Software without restriction, including without limitation the rights
* as published by the Free Software Foundation. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* * copies of the Software, and to permit persons to whom the Software is
* This program is distributed in the hope that it will be useful, * furnished to do so, subject to the following conditions:
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * The above copyright notice and this permission notice shall be included in
* GNU General Public License for more details. * all copies or substantial portions of the Software.
* *
* You should have received a copy of the GNU General Public License * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* along with this program. If not, see <http://www.gnu.org/licenses/>. * 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.operations.remote; package com.owncloud.android.lib.operations.remote;
import java.io.IOException;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import android.util.Log; import android.util.Log;
@ -77,8 +80,10 @@ public class GetUserNameRemoteOperation extends RemoteOperation {
//Get the user //Get the user
try { try {
//GetMethod get = new GetMethod(client.getWebdavUri() + OCS_ROUTE);
get = new GetMethod(client.getBaseUri() + 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.getBaseUri() + OCS_ROUTE);
Log.e(TAG, "Getting OC user information from " + client.getWebdavUri() + OCS_ROUTE);
// Add the Header // Add the Header
get.addRequestHeader(HEADER_OCS_API, HEADER_OCS_API_VALUE); get.addRequestHeader(HEADER_OCS_API, HEADER_OCS_API_VALUE);
status = client.executeMethod(get); status = client.executeMethod(get);

View File

@ -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.operations.remote;
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.accounts.AccountUtils;
import com.owncloud.android.lib.network.OwnCloudClient;
import com.owncloud.android.lib.operations.common.RemoteOperation;
import com.owncloud.android.lib.operations.common.RemoteOperationResult;
import com.owncloud.android.lib.utils.OwnCloudVersion;
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;
}
}

View File

@ -77,7 +77,7 @@ public class ReadRemoteFileOperation extends RemoteOperation {
/// take the duty of check the server for the current state of the file there /// take the duty of check the server for the current state of the file there
try { try {
propfind = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath), propfind = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
DavConstants.PROPFIND_ALL_PROP, DavConstants.PROPFIND_ALL_PROP,
DavConstants.DEPTH_0); DavConstants.DEPTH_0);
int status; int status;
@ -87,9 +87,9 @@ public class ReadRemoteFileOperation extends RemoteOperation {
if (isMultiStatus) { if (isMultiStatus) {
// Parse response // Parse response
MultiStatus resp = propfind.getResponseBodyAsMultiStatus(); MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath()); WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getWebdavUri().getPath());
RemoteFile remoteFile = new RemoteFile(we); RemoteFile remoteFile = new RemoteFile(we);
ArrayList<RemoteFile> files = new ArrayList<RemoteFile>(); ArrayList<Object> files = new ArrayList<Object>();
files.add(remoteFile); files.add(remoteFile);
// Result of the operation // Result of the operation

View File

@ -52,7 +52,7 @@ public class ReadRemoteFolderOperation extends RemoteOperation {
private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName(); private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName();
private String mRemotePath; private String mRemotePath;
private ArrayList<RemoteFile> mFolderAndFiles; private ArrayList<Object> mFolderAndFiles;
/** /**
* Constructor * Constructor
@ -75,7 +75,7 @@ public class ReadRemoteFolderOperation extends RemoteOperation {
try { try {
// remote request // remote request
query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath), query = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
DavConstants.PROPFIND_ALL_PROP, DavConstants.PROPFIND_ALL_PROP,
DavConstants.DEPTH_1); DavConstants.DEPTH_1);
int status = client.executeMethod(query); int status = client.executeMethod(query);
@ -134,17 +134,17 @@ public class ReadRemoteFolderOperation extends RemoteOperation {
* @return * @return
*/ */
private void readData(MultiStatus dataInServer, OwnCloudClient client) { private void readData(MultiStatus dataInServer, OwnCloudClient client) {
mFolderAndFiles = new ArrayList<RemoteFile>(); mFolderAndFiles = new ArrayList<Object>();
// parse data from remote folder // parse data from remote folder
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath()); WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getWebdavUri().getPath());
mFolderAndFiles.add(fillOCFile(we)); mFolderAndFiles.add(fillOCFile(we));
// loop to update every child // loop to update every child
RemoteFile remoteFile = null; RemoteFile remoteFile = null;
for (int i = 1; i < dataInServer.getResponses().length; ++i) { for (int i = 1; i < dataInServer.getResponses().length; ++i) {
/// new OCFile instance with the data from the server /// new OCFile instance with the data from the server
we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath()); we = new WebdavEntry(dataInServer.getResponses()[i], client.getWebdavUri().getPath());
remoteFile = fillOCFile(we); remoteFile = fillOCFile(we);
mFolderAndFiles.add(remoteFile); mFolderAndFiles.add(remoteFile);
} }

View File

@ -68,7 +68,7 @@ public class RemoveRemoteFileOperation extends RemoteOperation {
DeleteMethod delete = null; DeleteMethod delete = null;
try { try {
delete = new DeleteMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); delete = new DeleteMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT); int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT);
delete.getResponseBodyAsString(); // exhaust the response, although not interesting delete.getResponseBodyAsString(); // exhaust the response, although not interesting

View File

@ -104,8 +104,8 @@ public class RenameRemoteFileOperation extends RemoteOperation {
return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE); return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
} }
move = new LocalMoveMethod( client.getBaseUri() + WebdavUtils.encodePath(mOldRemotePath), move = new LocalMoveMethod( client.getWebdavUri() + WebdavUtils.encodePath(mOldRemotePath),
client.getBaseUri() + WebdavUtils.encodePath(mNewRemotePath)); client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath));
int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT); int status = client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT);
move.getResponseBodyAsString(); // exhaust response, although not interesting move.getResponseBodyAsString(); // exhaust response, although not interesting

View File

@ -80,7 +80,7 @@ public class UploadRemoteFileOperation extends RemoteOperation {
if (mCancellationRequested.get()) { if (mCancellationRequested.get()) {
throw new OperationCancelledException(); throw new OperationCancelledException();
} else { } else {
mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
} }
} }

View File

@ -54,6 +54,17 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
mIsValid = false; mIsValid = false;
parseVersionString(version); parseVersionString(version);
} }
public OwnCloudVersion(String versionstring, boolean isVersionString) {
mVersion = 0;
mIsValid = false;
if (isVersionString) {
parseVersionString(versionstring);
} else {
parseVersion(versionstring);
}
}
public String toString() { public String toString() {
return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "." return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "."
@ -70,7 +81,7 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
: another.mVersion < mVersion ? 1 : -1; : another.mVersion < mVersion ? 1 : -1;
} }
private void parseVersionString(String version) { private void parseVersion(String version) {
try { try {
String[] nums = version.split("\\."); String[] nums = version.split("\\.");
if (nums.length > 0) { if (nums.length > 0) {
@ -89,4 +100,26 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
mIsValid = false; 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;
}
}
} }

View File

@ -0,0 +1,348 @@
/* 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.utils;
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.operations.common.OCShare;
import com.owncloud.android.lib.operations.common.ShareType;
/**
* 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 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 ShareXMLParser() {
}
/**
* 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_ID)) {
share.setIdRemoteShared(Integer.parseInt(readNode(parser, NODE_ID)));
} else if (name.equalsIgnoreCase(NODE_ITEM_TYPE)) {
share.setIsDirectory(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;
}
}
}
}