mirror of
https://github.com/owncloud/android-library.git
synced 2026-08-13 09:23:00 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -49,13 +49,15 @@ import android.net.Uri;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||
import com.owncloud.android.lib.common.network.RedirectionPath;
|
||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
public class OwnCloudClient extends HttpClient {
|
||||
|
||||
private static final String TAG = OwnCloudClient.class.getSimpleName();
|
||||
private static final int MAX_REDIRECTIONS_COUNT = 3;
|
||||
public static final int MAX_REDIRECTIONS_COUNT = 3;
|
||||
private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
|
||||
private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
|
||||
|
||||
@@ -67,6 +69,8 @@ public class OwnCloudClient extends HttpClient {
|
||||
private int mInstanceNumber = 0;
|
||||
|
||||
private Uri mBaseUri;
|
||||
|
||||
private OwnCloudVersion mVersion = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -168,13 +172,13 @@ public class OwnCloudClient extends HttpClient {
|
||||
*
|
||||
* The timeouts are both in milliseconds; 0 means 'infinite';
|
||||
* < 0 means 'do not change the default'
|
||||
*
|
||||
*
|
||||
* @param method HTTP method request.
|
||||
* @param readTimeout Timeout to set for data reception
|
||||
* @param connectionTimeout Timeout to set for connection establishment
|
||||
*/
|
||||
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout)
|
||||
throws HttpException, IOException {
|
||||
public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws IOException {
|
||||
|
||||
int oldSoTimeout = getParams().getSoTimeout();
|
||||
int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
|
||||
try {
|
||||
@@ -191,55 +195,53 @@ public class OwnCloudClient extends HttpClient {
|
||||
getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int executeMethod(HttpMethod method) throws IOException, HttpException {
|
||||
try { // just to log
|
||||
boolean customRedirectionNeeded = false;
|
||||
|
||||
try {
|
||||
method.setFollowRedirects(mFollowRedirects);
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
if (mFollowRedirects)
|
||||
Log_OC.d(TAG, "setFollowRedirects failed for " + method.getName()
|
||||
+ " method, custom redirection will be used if needed");
|
||||
*/
|
||||
customRedirectionNeeded = mFollowRedirects;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Requests the received method.
|
||||
*
|
||||
* Executes the method through the inherited HttpClient.executedMethod(method).
|
||||
*
|
||||
* @param method HTTP method request.
|
||||
*/
|
||||
@Override
|
||||
public int executeMethod(HttpMethod method) throws IOException {
|
||||
try {
|
||||
// Update User Agent
|
||||
HttpParams params = method.getParams();
|
||||
String userAgent = OwnCloudClientManagerFactory.getUserAgent();
|
||||
params.setParameter(HttpMethodParams.USER_AGENT, userAgent);
|
||||
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
|
||||
method.getName() + " " + method.getPath());
|
||||
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
|
||||
method.getName() + " " + method.getPath());
|
||||
|
||||
// logCookiesAtRequest(method.getRequestHeaders(), "before");
|
||||
// logCookiesAtState("before");
|
||||
|
||||
int status = super.executeMethod(method);
|
||||
|
||||
if (customRedirectionNeeded) {
|
||||
status = patchRedirection(status, method);
|
||||
}
|
||||
method.setFollowRedirects(false);
|
||||
|
||||
int status = super.executeMethod(method);
|
||||
|
||||
if (mFollowRedirects) {
|
||||
status = followRedirection(method).getLastStatus();
|
||||
}
|
||||
|
||||
// logCookiesAtRequest(method.getRequestHeaders(), "after");
|
||||
// logCookiesAtState("after");
|
||||
// logSetCookiesAtResponse(method.getResponseHeaders());
|
||||
|
||||
return status;
|
||||
|
||||
|
||||
return status;
|
||||
|
||||
} catch (IOException e) {
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e);
|
||||
throw e;
|
||||
//Log_OC.d(TAG + " #" + mInstanceNumber, "Exception occurred", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private int patchRedirection(int status, HttpMethod method) throws HttpException, IOException {
|
||||
|
||||
public RedirectionPath followRedirection(HttpMethod method) throws IOException {
|
||||
int redirectionsCount = 0;
|
||||
int status = method.getStatusCode();
|
||||
RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
|
||||
while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
|
||||
( status == HttpStatus.SC_MOVED_PERMANENTLY ||
|
||||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
|
||||
@@ -254,18 +256,20 @@ public class OwnCloudClient extends HttpClient {
|
||||
Log_OC.d(TAG + " #" + mInstanceNumber,
|
||||
"Location to redirect: " + location.getValue());
|
||||
|
||||
String locationStr = location.getValue();
|
||||
result.addLocation(locationStr);
|
||||
|
||||
// Release the connection to avoid reach the max number of connections per host
|
||||
// due to it will be set a different url
|
||||
exhaustResponse(method.getResponseBodyAsStream());
|
||||
method.releaseConnection();
|
||||
|
||||
method.setURI(new URI(location.getValue(), true));
|
||||
method.setURI(new URI(locationStr, true));
|
||||
Header destination = method.getRequestHeader("Destination");
|
||||
if (destination == null) {
|
||||
destination = method.getRequestHeader("destination");
|
||||
}
|
||||
if (destination != null) {
|
||||
String locationStr = location.getValue();
|
||||
int suffixIndex = locationStr.lastIndexOf(
|
||||
(mCredentials instanceof OwnCloudBearerCredentials) ?
|
||||
AccountUtils.ODAV_PATH :
|
||||
@@ -281,6 +285,7 @@ public class OwnCloudClient extends HttpClient {
|
||||
method.setRequestHeader(destination);
|
||||
}
|
||||
status = super.executeMethod(method);
|
||||
result.addStatus(status);
|
||||
redirectionsCount++;
|
||||
|
||||
} else {
|
||||
@@ -288,7 +293,7 @@ public class OwnCloudClient extends HttpClient {
|
||||
status = HttpStatus.SC_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,7 +361,10 @@ public class OwnCloudClient extends HttpClient {
|
||||
mFollowRedirects = followRedirects;
|
||||
}
|
||||
|
||||
|
||||
public boolean getFollowRedirects() {
|
||||
return mFollowRedirects;
|
||||
}
|
||||
|
||||
private void logCookiesAtRequest(Header[] headers, String when) {
|
||||
int counter = 0;
|
||||
for (int i=0; i<headers.length; i++) {
|
||||
@@ -436,4 +444,11 @@ public class OwnCloudClient extends HttpClient {
|
||||
}
|
||||
|
||||
|
||||
public void setOwnCloudVersion(OwnCloudVersion version){
|
||||
mVersion = version;
|
||||
}
|
||||
|
||||
public OwnCloudVersion getOwnCloudVersion(){
|
||||
return mVersion;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,8 +82,9 @@ public class OwnCloudClientFactory {
|
||||
boolean isSamlSso =
|
||||
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
||||
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
||||
|
||||
if (isOauth2) {
|
||||
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
if (isOauth2) {
|
||||
String accessToken = am.blockingGetAuthToken(
|
||||
account,
|
||||
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
|
||||
@@ -100,11 +101,10 @@ public class OwnCloudClientFactory {
|
||||
false);
|
||||
|
||||
client.setCredentials(
|
||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken)
|
||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken)
|
||||
);
|
||||
|
||||
} else {
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
//String password = am.getPassword(account);
|
||||
String password = am.blockingGetAuthToken(
|
||||
account,
|
||||
@@ -136,7 +136,8 @@ public class OwnCloudClientFactory {
|
||||
boolean isSamlSso =
|
||||
am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
||||
OwnCloudClient client = createOwnCloudClient(baseUri, appContext, !isSamlSso);
|
||||
|
||||
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
if (isOauth2) { // TODO avoid a call to getUserData here
|
||||
AccountManagerFuture<Bundle> future = am.getAuthToken(
|
||||
account,
|
||||
@@ -166,12 +167,11 @@ public class OwnCloudClientFactory {
|
||||
String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
if (accessToken == null) throw new AuthenticatorException("WTF!");
|
||||
client.setCredentials(
|
||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken)
|
||||
OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken)
|
||||
);
|
||||
|
||||
|
||||
} else {
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
//String password = am.getPassword(account);
|
||||
//String password = am.blockingGetAuthToken(account, MainApp.getAuthTokenTypePass(),
|
||||
// false);
|
||||
|
||||
@@ -36,8 +36,8 @@ public class OwnCloudCredentialsFactory {
|
||||
return new OwnCloudBearerCredentials(authToken);
|
||||
}
|
||||
|
||||
public static OwnCloudCredentials newSamlSsoCredentials(String sessionCookie) {
|
||||
return new OwnCloudSamlSsoCredentials(sessionCookie);
|
||||
public static OwnCloudCredentials newSamlSsoCredentials(String username, String sessionCookie) {
|
||||
return new OwnCloudSamlSsoCredentials(username, sessionCookie);
|
||||
}
|
||||
|
||||
public static final OwnCloudCredentials getAnonymousCredentials() {
|
||||
|
||||
@@ -30,9 +30,11 @@ import android.net.Uri;
|
||||
|
||||
public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
||||
|
||||
private String mUsername;
|
||||
private String mSessionCookie;
|
||||
|
||||
public OwnCloudSamlSsoCredentials(String sessionCookie) {
|
||||
public OwnCloudSamlSsoCredentials(String username, String sessionCookie) {
|
||||
mUsername = username != null ? username : "";
|
||||
mSessionCookie = sessionCookie != null ? sessionCookie : "";
|
||||
}
|
||||
|
||||
@@ -63,8 +65,8 @@ public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
// its unknown
|
||||
return null;
|
||||
// not relevant for authentication, but relevant for informational purposes
|
||||
return mUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -167,7 +167,9 @@ public class AccountUtils {
|
||||
boolean isSamlSso = am.getUserData(
|
||||
account,
|
||||
AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null;
|
||||
|
||||
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
|
||||
if (isOauth2) {
|
||||
String accessToken = am.blockingGetAuthToken(
|
||||
account,
|
||||
@@ -182,10 +184,9 @@ public class AccountUtils {
|
||||
AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type),
|
||||
false);
|
||||
|
||||
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(accessToken);
|
||||
credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken);
|
||||
|
||||
} else {
|
||||
String username = account.name.substring(0, account.name.lastIndexOf('@'));
|
||||
String password = am.blockingGetAuthToken(
|
||||
account,
|
||||
AccountTypeUtils.getAuthTokenTypePass(account.type),
|
||||
@@ -199,7 +200,7 @@ public class AccountUtils {
|
||||
}
|
||||
|
||||
|
||||
public static String buildAccountName(Uri serverBaseUrl, String username) {
|
||||
public static String buildAccountNameOld(Uri serverBaseUrl, String username) {
|
||||
if (serverBaseUrl.getScheme() == null) {
|
||||
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
|
||||
}
|
||||
@@ -209,7 +210,21 @@ public class AccountUtils {
|
||||
}
|
||||
return accountName;
|
||||
}
|
||||
|
||||
|
||||
public static String buildAccountName(Uri serverBaseUrl, String username) {
|
||||
if (serverBaseUrl.getScheme() == null) {
|
||||
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
|
||||
}
|
||||
|
||||
// Remove http:// or https://
|
||||
String url = serverBaseUrl.toString();
|
||||
if (url.contains("://")) {
|
||||
url = url.substring(serverBaseUrl.toString().indexOf("://") + 3);
|
||||
}
|
||||
String accountName = username + "@" + url;
|
||||
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) {
|
||||
|
||||
@@ -336,12 +351,18 @@ public class AccountUtils {
|
||||
public static final String KEY_SUPPORTS_SAML_WEB_SSO = "oc_supports_saml_web_sso";
|
||||
/**
|
||||
* Flag signaling if the ownCloud server supports Share API"
|
||||
*/
|
||||
* @deprecated
|
||||
*/
|
||||
public static final String KEY_SUPPORTS_SHARE_API = "oc_supports_share_api";
|
||||
/**
|
||||
* OC accout cookies
|
||||
* OC account cookies
|
||||
*/
|
||||
public static final String KEY_COOKIES = "oc_account_cookies";
|
||||
}
|
||||
|
||||
/**
|
||||
* OC account version
|
||||
*/
|
||||
public static final String KEY_OC_ACCOUNT_VERSION = "oc_account_version";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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.common.network;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Aggregate saving the list of URLs followed in a sequence of redirections during the exceution of a
|
||||
* {@link com.owncloud.android.lib.common.operations.RemoteOperation}, and the status codes corresponding to all
|
||||
* of them.
|
||||
*
|
||||
* The last status code saved corresponds to the first response not being a redirection, unless the sequence exceeds
|
||||
* the maximum length of redirections allowed by the {@link com.owncloud.android.lib.common.OwnCloudClient} instance
|
||||
* that ran the operation.
|
||||
*
|
||||
* If no redirection was followed, the last (and first) status code contained corresponds to the original URL in the
|
||||
* request.
|
||||
*/
|
||||
public class RedirectionPath {
|
||||
|
||||
private int[] mStatuses = null;
|
||||
|
||||
private int mLastStatus = -1;
|
||||
|
||||
private String[] mLocations = null;
|
||||
|
||||
private int mLastLocation = -1;
|
||||
private int maxRedirections;
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @param status Status code resulting of executing a request on the original URL.
|
||||
* @param maxRedirections Maximum number of redirections that will be contained.
|
||||
* @throws IllegalArgumentException If 'maxRedirections' is < 0
|
||||
*/
|
||||
public RedirectionPath(int status, int maxRedirections) {
|
||||
if (maxRedirections < 0) {
|
||||
throw new IllegalArgumentException("maxRedirections MUST BE zero or greater");
|
||||
}
|
||||
mStatuses = new int[maxRedirections + 1];
|
||||
Arrays.fill(mStatuses, -1);
|
||||
mStatuses[++mLastStatus] = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new location URL to the list of followed redirections.
|
||||
*
|
||||
* @param location URL extracted from a 'Location' header in a redirection.
|
||||
*/
|
||||
public void addLocation(String location) {
|
||||
if (mLocations == null) {
|
||||
mLocations = new String[mStatuses.length - 1];
|
||||
}
|
||||
if (mLastLocation < mLocations.length - 1) {
|
||||
mLocations[++mLastLocation] = location;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new status code to the list of status corresponding to followed redirections.
|
||||
*
|
||||
* @param status Status code from the response of another followed redirection.
|
||||
*/
|
||||
public void addStatus(int status) {
|
||||
if (mLastStatus < mStatuses.length - 1) {
|
||||
mStatuses[++mLastStatus] = status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last status code saved.
|
||||
*/
|
||||
public int getLastStatus() {
|
||||
return mStatuses[mLastStatus];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last location followed corresponding to a permanent redirection (status code 301).
|
||||
*/
|
||||
public String getLastPermanentLocation() {
|
||||
for (int i = mLastStatus; i >= 0; i--) {
|
||||
if (mStatuses[i] == HttpStatus.SC_MOVED_PERMANENTLY && i <= mLastLocation) {
|
||||
return mLocations[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Count of locations.
|
||||
*/
|
||||
public int getRedirectionsCount() {
|
||||
return mLastLocation + 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
package com.owncloud.android.lib.common.network;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
||||
@@ -37,6 +38,9 @@ import android.net.Uri;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
public class WebdavEntry {
|
||||
|
||||
private static final String TAG = WebdavEntry.class.getSimpleName();
|
||||
|
||||
public static final String NAMESPACE_OC = "http://owncloud.org/ns";
|
||||
public static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions";
|
||||
public static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id";
|
||||
@@ -49,7 +53,7 @@ public class WebdavEntry {
|
||||
|
||||
private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId;
|
||||
private long mContentLength, mCreateTimestamp, mModifiedTimestamp, mSize;
|
||||
private long mQuotaUsedBytes, mQuotaAvailableBytes;
|
||||
private BigDecimal mQuotaUsedBytes, mQuotaAvailableBytes;
|
||||
|
||||
public WebdavEntry(MultiStatusResponse ms, String splitElement) {
|
||||
resetData();
|
||||
@@ -125,20 +129,37 @@ public class WebdavEntry {
|
||||
prop = propSet.get(DavPropertyName.GETETAG);
|
||||
if (prop != null) {
|
||||
mEtag = (String) prop.getValue();
|
||||
mEtag = mEtag.substring(1, mEtag.length()-1);
|
||||
mEtag = WebdavUtils.parseEtag(mEtag);
|
||||
}
|
||||
|
||||
// {DAV:}quota-used-bytes
|
||||
prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_USED_BYTES));
|
||||
if (prop != null) {
|
||||
mQuotaUsedBytes = Long.parseLong((String) prop.getValue());
|
||||
String quotaUsedBytesSt = (String) prop.getValue();
|
||||
try {
|
||||
mQuotaUsedBytes = new BigDecimal(quotaUsedBytesSt);
|
||||
} catch (NumberFormatException e) {
|
||||
Log_OC.w(TAG, "No value for QuotaUsedBytes - NumberFormatException");
|
||||
} catch (NullPointerException e ){
|
||||
Log_OC.w(TAG, "No value for QuotaUsedBytes - NullPointerException");
|
||||
}
|
||||
Log_OC.d(TAG , "QUOTA_USED_BYTES " + quotaUsedBytesSt );
|
||||
}
|
||||
|
||||
// {DAV:}quota-available-bytes
|
||||
prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_AVAILABLE_BYTES));
|
||||
if (prop != null) {
|
||||
mQuotaAvailableBytes = Long.parseLong((String) prop.getValue());
|
||||
String quotaAvailableBytesSt = (String) prop.getValue();
|
||||
try {
|
||||
mQuotaAvailableBytes = new BigDecimal(quotaAvailableBytesSt);
|
||||
} catch (NumberFormatException e) {
|
||||
Log_OC.w(TAG, "No value for QuotaAvailableBytes - NumberFormatException");
|
||||
} catch (NullPointerException e ){
|
||||
Log_OC.w(TAG, "No value for QuotaAvailableBytes");
|
||||
}
|
||||
Log_OC.d(TAG , "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt );
|
||||
}
|
||||
|
||||
// OC permissions property <oc:permissions>
|
||||
prop = propSet.get(
|
||||
EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC)
|
||||
@@ -222,11 +243,11 @@ public class WebdavEntry {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
public long quotaUsedBytes() {
|
||||
public BigDecimal quotaUsedBytes() {
|
||||
return mQuotaUsedBytes;
|
||||
}
|
||||
|
||||
public long quotaAvailableBytes() {
|
||||
public BigDecimal quotaAvailableBytes() {
|
||||
return mQuotaAvailableBytes;
|
||||
}
|
||||
|
||||
@@ -234,7 +255,7 @@ public class WebdavEntry {
|
||||
mName = mUri = mContentType = mPermissions = null; mRemoteId = null;
|
||||
mContentLength = mCreateTimestamp = mModifiedTimestamp = 0;
|
||||
mSize = 0;
|
||||
mQuotaUsedBytes = 0;
|
||||
mQuotaAvailableBytes = 0;
|
||||
mQuotaUsedBytes = null;
|
||||
mQuotaAvailableBytes = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ import java.util.Locale;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
import org.apache.jackrabbit.webdav.property.DavPropertyName;
|
||||
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
|
||||
import org.apache.jackrabbit.webdav.xml.Namespace;
|
||||
@@ -131,4 +133,47 @@ public class WebdavUtils {
|
||||
|
||||
return propSet;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rawEtag
|
||||
* @return
|
||||
*/
|
||||
public static String parseEtag(String rawEtag) {
|
||||
if (rawEtag == null || rawEtag.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
if (rawEtag.endsWith("-gzip")) {
|
||||
rawEtag = rawEtag.substring(0, rawEtag.length() - 5);
|
||||
}
|
||||
if (rawEtag.length() >= 2 && rawEtag.startsWith("\"") && rawEtag.endsWith("\"")) {
|
||||
rawEtag = rawEtag.substring(1, rawEtag.length() - 1);
|
||||
}
|
||||
return rawEtag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param method
|
||||
* @return
|
||||
*/
|
||||
public static String getEtagFromResponse(HttpMethod method) {
|
||||
Header eTag = method.getResponseHeader("OC-ETag");
|
||||
if (eTag == null) {
|
||||
eTag = method.getResponseHeader("oc-etag");
|
||||
}
|
||||
if (eTag == null) {
|
||||
eTag = method.getResponseHeader("ETag");
|
||||
}
|
||||
if (eTag == null) {
|
||||
eTag = method.getResponseHeader("etag");
|
||||
}
|
||||
String result = "";
|
||||
if (eTag != null) {
|
||||
result = parseEtag(eTag.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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.common.operations;
|
||||
|
||||
import android.util.Xml;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Parser for Invalid Character server exception
|
||||
* @author masensio
|
||||
*/
|
||||
public class InvalidCharacterExceptionParser {
|
||||
|
||||
private static final String EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath";
|
||||
private static final String EXCEPTION_UPLOAD_STRING = "OCP\\Files\\InvalidPathException";
|
||||
|
||||
// No namespaces
|
||||
private static final String ns = null;
|
||||
|
||||
// Nodes for XML Parser
|
||||
private static final String NODE_ERROR = "d:error";
|
||||
private static final String NODE_EXCEPTION = "s:exception";
|
||||
/**
|
||||
* Parse is as an Invalid Path Exception
|
||||
* @param is
|
||||
* @return if The exception is an Invalid Char Exception
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean parseXMLResponse(InputStream is) throws XmlPullParserException,
|
||||
IOException {
|
||||
boolean result = false;
|
||||
|
||||
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();
|
||||
result = readError(parser);
|
||||
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse OCS node
|
||||
* @param parser
|
||||
* @return List of ShareRemoteFiles
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean readError (XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
String exception = "";
|
||||
parser.require(XmlPullParser.START_TAG, ns , NODE_ERROR);
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
// read NODE_EXCEPTION
|
||||
if (name.equalsIgnoreCase(NODE_EXCEPTION)) {
|
||||
exception = readText(parser);
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
|
||||
}
|
||||
return exception.equalsIgnoreCase(EXCEPTION_STRING) ||
|
||||
exception.equalsIgnoreCase(EXCEPTION_UPLOAD_STRING);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
package com.owncloud.android.lib.common.operations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountsException;
|
||||
@@ -42,6 +40,8 @@ import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Operation which execution involves one or several interactions with an ownCloud server.
|
||||
|
||||
@@ -24,15 +24,21 @@
|
||||
|
||||
package com.owncloud.android.lib.common.operations;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountsException;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||
import com.owncloud.android.lib.common.network.CertificateCombinedException;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.ConnectTimeoutException;
|
||||
import org.apache.commons.httpclient.Header;
|
||||
@@ -41,60 +47,55 @@ import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.jackrabbit.webdav.DavException;
|
||||
import org.json.JSONException;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountsException;
|
||||
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||
import com.owncloud.android.lib.common.network.CertificateCombinedException;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
|
||||
/**
|
||||
* The result of a remote operation required to an ownCloud server.
|
||||
*
|
||||
* <p/>
|
||||
* Provides a common classification of remote operation results for all the
|
||||
* application.
|
||||
*
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public class RemoteOperationResult implements Serializable {
|
||||
|
||||
|
||||
/** Generated - should be refreshed every time the class changes!! */;
|
||||
private static final long serialVersionUID = -9003837206000993465L;
|
||||
|
||||
private static final String TAG = "RemoteOperationResult";
|
||||
|
||||
public enum ResultCode {
|
||||
private static final long serialVersionUID = 1129130415603799707L;
|
||||
|
||||
private static final String TAG = RemoteOperationResult.class.getSimpleName();
|
||||
|
||||
public enum ResultCode {
|
||||
OK,
|
||||
OK_SSL,
|
||||
OK_NO_SSL,
|
||||
UNHANDLED_HTTP_CODE,
|
||||
UNAUTHORIZED,
|
||||
FILE_NOT_FOUND,
|
||||
INSTANCE_NOT_CONFIGURED,
|
||||
UNKNOWN_ERROR,
|
||||
WRONG_CONNECTION,
|
||||
TIMEOUT,
|
||||
INCORRECT_ADDRESS,
|
||||
HOST_NOT_AVAILABLE,
|
||||
NO_NETWORK_CONNECTION,
|
||||
UNAUTHORIZED,
|
||||
FILE_NOT_FOUND,
|
||||
INSTANCE_NOT_CONFIGURED,
|
||||
UNKNOWN_ERROR,
|
||||
WRONG_CONNECTION,
|
||||
TIMEOUT,
|
||||
INCORRECT_ADDRESS,
|
||||
HOST_NOT_AVAILABLE,
|
||||
NO_NETWORK_CONNECTION,
|
||||
SSL_ERROR,
|
||||
SSL_RECOVERABLE_PEER_UNVERIFIED,
|
||||
BAD_OC_VERSION,
|
||||
CANCELLED,
|
||||
INVALID_LOCAL_FILE_NAME,
|
||||
CANCELLED,
|
||||
INVALID_LOCAL_FILE_NAME,
|
||||
INVALID_OVERWRITE,
|
||||
CONFLICT,
|
||||
CONFLICT,
|
||||
OAUTH2_ERROR,
|
||||
SYNC_CONFLICT,
|
||||
LOCAL_STORAGE_FULL,
|
||||
LOCAL_STORAGE_NOT_MOVED,
|
||||
LOCAL_STORAGE_NOT_COPIED,
|
||||
LOCAL_STORAGE_FULL,
|
||||
LOCAL_STORAGE_NOT_MOVED,
|
||||
LOCAL_STORAGE_NOT_COPIED,
|
||||
OAUTH2_ERROR_ACCESS_DENIED,
|
||||
QUOTA_EXCEEDED,
|
||||
ACCOUNT_NOT_FOUND,
|
||||
ACCOUNT_EXCEPTION,
|
||||
ACCOUNT_NOT_NEW,
|
||||
QUOTA_EXCEEDED,
|
||||
ACCOUNT_NOT_FOUND,
|
||||
ACCOUNT_EXCEPTION,
|
||||
ACCOUNT_NOT_NEW,
|
||||
ACCOUNT_NOT_THE_SAME,
|
||||
INVALID_CHARACTER_IN_NAME,
|
||||
SHARE_NOT_FOUND,
|
||||
@@ -102,8 +103,12 @@ public class RemoteOperationResult implements Serializable {
|
||||
FORBIDDEN,
|
||||
SHARE_FORBIDDEN,
|
||||
OK_REDIRECT_TO_NON_SECURE_CONNECTION,
|
||||
INVALID_MOVE_INTO_DESCENDANT,
|
||||
PARTIAL_MOVE_DONE
|
||||
INVALID_MOVE_INTO_DESCENDANT,
|
||||
INVALID_COPY_INTO_DESCENDANT,
|
||||
PARTIAL_MOVE_DONE,
|
||||
PARTIAL_COPY_DONE,
|
||||
SHARE_WRONG_PARAMETER,
|
||||
WRONG_SERVER_RESPONSE, INVALID_CHARACTER_DETECT_IN_SERVER
|
||||
}
|
||||
|
||||
private boolean mSuccess = false;
|
||||
@@ -112,12 +117,15 @@ public class RemoteOperationResult implements Serializable {
|
||||
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
|
||||
private String mRedirectedLocation;
|
||||
private String mAuthenticate;
|
||||
private String mLastPermanentLocation = null;
|
||||
|
||||
private ArrayList<Object> mData;
|
||||
|
||||
public RemoteOperationResult(ResultCode code) {
|
||||
mCode = code;
|
||||
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL || code == ResultCode.OK_NO_SSL || code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION);
|
||||
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL ||
|
||||
code == ResultCode.OK_NO_SSL ||
|
||||
code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION);
|
||||
mData = null;
|
||||
}
|
||||
|
||||
@@ -147,31 +155,63 @@ public class RemoteOperationResult implements Serializable {
|
||||
break;
|
||||
case HttpStatus.SC_FORBIDDEN:
|
||||
mCode = ResultCode.FORBIDDEN;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
mCode = ResultCode.UNHANDLED_HTTP_CODE;
|
||||
Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + httpCode);
|
||||
Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " +
|
||||
httpCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RemoteOperationResult(boolean success, int httpCode, Header[] headers) {
|
||||
this(success, httpCode);
|
||||
if (headers != null) {
|
||||
Header current;
|
||||
for (int i=0; i<headers.length; i++) {
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
current = headers[i];
|
||||
if ("location".equals(current.getName().toLowerCase())) {
|
||||
mRedirectedLocation = current.getValue();
|
||||
continue;
|
||||
}
|
||||
if ("www-authenticate".equals(current.getName().toLowerCase())) {
|
||||
mAuthenticate = current.getValue();
|
||||
continue;
|
||||
mAuthenticate = current.getValue();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteOperationResult(boolean success, String bodyResponse, int httpCode) {
|
||||
mSuccess = success;
|
||||
mHttpCode = httpCode;
|
||||
|
||||
if (success) {
|
||||
mCode = ResultCode.OK;
|
||||
|
||||
} else if (httpCode > 0) {
|
||||
switch (httpCode) {
|
||||
case HttpStatus.SC_BAD_REQUEST:
|
||||
|
||||
InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
|
||||
InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser();
|
||||
try {
|
||||
if (xmlParser.parseXMLResponse(is))
|
||||
mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER;
|
||||
|
||||
} catch (Exception e) {
|
||||
mCode = ResultCode.UNHANDLED_HTTP_CODE;
|
||||
Log_OC.e(TAG, "Exception reading exception from server", e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mCode = ResultCode.UNHANDLED_HTTP_CODE;
|
||||
Log_OC.d(TAG, "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " +
|
||||
httpCode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public RemoteOperationResult(Exception e) {
|
||||
mException = e;
|
||||
@@ -196,10 +236,10 @@ public class RemoteOperationResult implements Serializable {
|
||||
|
||||
} else if (e instanceof AccountNotFoundException) {
|
||||
mCode = ResultCode.ACCOUNT_NOT_FOUND;
|
||||
|
||||
|
||||
} else if (e instanceof AccountsException) {
|
||||
mCode = ResultCode.ACCOUNT_EXCEPTION;
|
||||
|
||||
|
||||
} else if (e instanceof SSLException || e instanceof RuntimeException) {
|
||||
CertificateCombinedException se = getCertificateCombinedException(e);
|
||||
if (se != null) {
|
||||
@@ -221,14 +261,14 @@ public class RemoteOperationResult implements Serializable {
|
||||
}
|
||||
|
||||
|
||||
public void setData(ArrayList<Object> files){
|
||||
mData = files;
|
||||
public void setData(ArrayList<Object> files) {
|
||||
mData = files;
|
||||
}
|
||||
|
||||
public ArrayList<Object> getData(){
|
||||
return mData;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<Object> getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return mSuccess;
|
||||
}
|
||||
@@ -253,9 +293,9 @@ public class RemoteOperationResult implements Serializable {
|
||||
return mCode == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
|
||||
}
|
||||
|
||||
public boolean isRedirectToNonSecureConnection() {
|
||||
return mCode == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION;
|
||||
}
|
||||
public boolean isRedirectToNonSecureConnection() {
|
||||
return mCode == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION;
|
||||
}
|
||||
|
||||
private CertificateCombinedException getCertificateCombinedException(Exception e) {
|
||||
CertificateCombinedException result = null;
|
||||
@@ -264,7 +304,8 @@ public class RemoteOperationResult implements Serializable {
|
||||
}
|
||||
Throwable cause = mException.getCause();
|
||||
Throwable previousCause = null;
|
||||
while (cause != null && cause != previousCause && !(cause instanceof CertificateCombinedException)) {
|
||||
while (cause != null && cause != previousCause &&
|
||||
!(cause instanceof CertificateCombinedException)) {
|
||||
previousCause = cause;
|
||||
cause = cause.getCause();
|
||||
}
|
||||
@@ -314,15 +355,17 @@ public class RemoteOperationResult implements Serializable {
|
||||
return "Unrecovered transport exception";
|
||||
|
||||
} else if (mException instanceof AccountNotFoundException) {
|
||||
Account failedAccount = ((AccountNotFoundException)mException).getFailedAccount();
|
||||
return mException.getMessage() + " (" + (failedAccount != null ? failedAccount.name : "NULL") + ")";
|
||||
Account failedAccount =
|
||||
((AccountNotFoundException)mException).getFailedAccount();
|
||||
return mException.getMessage() + " (" +
|
||||
(failedAccount != null ? failedAccount.name : "NULL") + ")";
|
||||
|
||||
} else if (mException instanceof AccountsException) {
|
||||
return "Exception while using account";
|
||||
|
||||
|
||||
} else if (mException instanceof JSONException) {
|
||||
return "JSON exception";
|
||||
|
||||
return "JSON exception";
|
||||
|
||||
} else {
|
||||
return "Unexpected exception";
|
||||
}
|
||||
@@ -348,13 +391,19 @@ public class RemoteOperationResult implements Serializable {
|
||||
|
||||
} else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
|
||||
return "Authenticated with a different account than the one updating";
|
||||
|
||||
} else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) {
|
||||
return "The file name contains an forbidden character";
|
||||
} else if (mCode == ResultCode.FILE_NOT_FOUND) {
|
||||
return "Local file does not exist";
|
||||
}
|
||||
|
||||
return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess() ? "success" : "fail") + ")";
|
||||
} else if (mCode == ResultCode.FILE_NOT_FOUND) {
|
||||
return "Local file does not exist";
|
||||
|
||||
} else if (mCode == ResultCode.SYNC_CONFLICT) {
|
||||
return "Synchronization conflict";
|
||||
}
|
||||
|
||||
return "Operation finished with HTTP status code " + mHttpCode + " (" +
|
||||
(isSuccess() ? "success" : "fail") + ")";
|
||||
|
||||
}
|
||||
|
||||
@@ -373,24 +422,32 @@ public class RemoteOperationResult implements Serializable {
|
||||
public String getRedirectedLocation() {
|
||||
return mRedirectedLocation;
|
||||
}
|
||||
|
||||
|
||||
public boolean isIdPRedirection() {
|
||||
return (mRedirectedLocation != null &&
|
||||
(mRedirectedLocation.toUpperCase().contains("SAML") ||
|
||||
mRedirectedLocation.toLowerCase().contains("wayf")));
|
||||
(mRedirectedLocation.toUpperCase().contains("SAML") ||
|
||||
mRedirectedLocation.toLowerCase().contains("wayf")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is a non https connection
|
||||
*
|
||||
* @return boolean true/false
|
||||
*/
|
||||
public boolean isNonSecureRedirection() {
|
||||
return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is a non https connection
|
||||
*
|
||||
* @return boolean true/false
|
||||
*/
|
||||
public boolean isNonSecureRedirection() {
|
||||
return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://")));
|
||||
}
|
||||
|
||||
public String getAuthenticateHeader() {
|
||||
return mAuthenticate;
|
||||
return mAuthenticate;
|
||||
}
|
||||
|
||||
public String getLastPermanentLocation() {
|
||||
return mLastPermanentLocation;
|
||||
}
|
||||
|
||||
public void setLastPermanentLocation(String lastPermanentLocation) {
|
||||
mLastPermanentLocation = lastPermanentLocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,8 +32,7 @@ public class Log_OC {
|
||||
}
|
||||
|
||||
public static void i(String TAG, String message){
|
||||
|
||||
// Write the log message to the file
|
||||
Log.i(TAG, message);
|
||||
appendLog(TAG+" : "+ message);
|
||||
}
|
||||
|
||||
@@ -61,7 +60,7 @@ public class Log_OC {
|
||||
}
|
||||
|
||||
public static void w(String TAG, String message) {
|
||||
Log.w(TAG,message);
|
||||
Log.w(TAG, message);
|
||||
appendLog(TAG+" : "+ message);
|
||||
}
|
||||
|
||||
@@ -100,8 +99,16 @@ public class Log_OC {
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if(mBuf != null) {
|
||||
try {
|
||||
mBuf.close();
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,10 +167,15 @@ public class Log_OC {
|
||||
mBuf.newLine();
|
||||
mBuf.write(text);
|
||||
mBuf.newLine();
|
||||
mBuf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
mBuf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if current log file size is bigger than the max file size defined
|
||||
if (mLogFile.length() > MAX_FILE_SIZE) {
|
||||
|
||||
+55
-11
@@ -24,19 +24,21 @@
|
||||
|
||||
package com.owncloud.android.lib.resources.files;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
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 com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
|
||||
@@ -44,14 +46,21 @@ 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 OC_CHUNK_SIZE_HEADER = "OC-Chunk-Size";
|
||||
private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName();
|
||||
|
||||
public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType) {
|
||||
super(storagePath, remotePath, mimeType);
|
||||
public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType){
|
||||
super(storagePath, remotePath, mimeType);
|
||||
}
|
||||
|
||||
public ChunkedUploadRemoteFileOperation(
|
||||
String storagePath, String remotePath, String mimeType, String requiredEtag
|
||||
){
|
||||
super(storagePath, remotePath, mimeType, requiredEtag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int uploadFile(OwnCloudClient client) throws HttpException, IOException {
|
||||
protected int uploadFile(OwnCloudClient client) throws IOException {
|
||||
int status = -1;
|
||||
|
||||
FileChannel channel = null;
|
||||
@@ -61,25 +70,60 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation
|
||||
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);
|
||||
((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);
|
||||
String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) +
|
||||
"-chunking-" + Math.abs((new Random()).nextInt(9000)+1000) + "-" ;
|
||||
long totalLength = file.length();
|
||||
long chunkCount = (long) Math.ceil((double)totalLength / CHUNK_SIZE);
|
||||
String chunkSizeStr = String.valueOf(CHUNK_SIZE);
|
||||
String totalLengthStr = String.valueOf(file.length());
|
||||
for (int chunkIndex = 0; chunkIndex < chunkCount ; chunkIndex++, offset += CHUNK_SIZE) {
|
||||
if (chunkIndex == chunkCount - 1) {
|
||||
chunkSizeStr = String.valueOf(CHUNK_SIZE * chunkCount - totalLength);
|
||||
}
|
||||
if (mPutMethod != null) {
|
||||
mPutMethod.releaseConnection(); // let the connection available for other methods
|
||||
mPutMethod.releaseConnection(); // let the connection available
|
||||
// for other methods
|
||||
}
|
||||
mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex);
|
||||
if (mRequiredEtag != null && mRequiredEtag.length() > 0) {
|
||||
mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\"");
|
||||
}
|
||||
mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER);
|
||||
((ChunkFromFileChannelRequestEntity)mEntity).setOffset(offset);
|
||||
mPutMethod.addRequestHeader(OC_CHUNK_SIZE_HEADER, chunkSizeStr);
|
||||
mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, totalLengthStr);
|
||||
((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset);
|
||||
mPutMethod.setRequestEntity(mEntity);
|
||||
if (mCancellationRequested.get()) {
|
||||
mPutMethod.abort();
|
||||
// next method will throw an exception
|
||||
}
|
||||
status = client.executeMethod(mPutMethod);
|
||||
|
||||
if (status == 400) {
|
||||
InvalidCharacterExceptionParser xmlParser =
|
||||
new InvalidCharacterExceptionParser();
|
||||
InputStream is = new ByteArrayInputStream(
|
||||
mPutMethod.getResponseBodyAsString().getBytes());
|
||||
try {
|
||||
mForbiddenCharsInServer = xmlParser.parseXMLResponse(is);
|
||||
|
||||
} catch (Exception e) {
|
||||
mForbiddenCharsInServer = false;
|
||||
Log_OC.e(TAG, "Exception reading exception from server", e);
|
||||
}
|
||||
}
|
||||
|
||||
client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
|
||||
Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ", chunk index " + chunkIndex + ", count " + chunkCount + ", HTTP result status " + status);
|
||||
Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath +
|
||||
", chunk index " + chunkIndex + ", count " + chunkCount +
|
||||
", HTTP result status " + status);
|
||||
|
||||
if (!isSuccess(status))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* Copyright (C) 2014 ownCloud Inc.
|
||||
*
|
||||
* 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 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;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.jackrabbit.webdav.DavException;
|
||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
|
||||
import org.apache.jackrabbit.webdav.Status;
|
||||
import org.apache.jackrabbit.webdav.client.methods.CopyMethod;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Remote operation moving a remote file or folder in the ownCloud server to a different folder
|
||||
* in the same account.
|
||||
* <p/>
|
||||
* Allows renaming the moving file/folder at the same time.
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public class CopyRemoteFileOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = CopyRemoteFileOperation.class.getSimpleName();
|
||||
|
||||
private static final int COPY_READ_TIMEOUT = 600000;
|
||||
private static final int COPY_CONNECTION_TIMEOUT = 5000;
|
||||
|
||||
private String mSrcRemotePath;
|
||||
private String mTargetRemotePath;
|
||||
|
||||
private boolean mOverwrite;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* <p/>
|
||||
* TODO Paths should finish in "/" in the case of folders. ?
|
||||
*
|
||||
* @param srcRemotePath Remote path of the file/folder to move.
|
||||
* @param targetRemotePath Remove path desired for the file/folder after moving it.
|
||||
*/
|
||||
public CopyRemoteFileOperation(String srcRemotePath, String targetRemotePath, boolean overwrite
|
||||
) {
|
||||
mSrcRemotePath = srcRemotePath;
|
||||
mTargetRemotePath = targetRemotePath;
|
||||
mOverwrite = overwrite;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs the rename operation.
|
||||
*
|
||||
* @param client Client object to communicate with the remote ownCloud server.
|
||||
*/
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
|
||||
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||
boolean versionWithForbiddenChars =
|
||||
(version != null && version.isVersionWithForbiddenCharacters());
|
||||
|
||||
/// check parameters
|
||||
if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) {
|
||||
return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
||||
}
|
||||
|
||||
if (mTargetRemotePath.equals(mSrcRemotePath)) {
|
||||
// nothing to do!
|
||||
return new RemoteOperationResult(ResultCode.OK);
|
||||
}
|
||||
|
||||
if (mTargetRemotePath.startsWith(mSrcRemotePath)) {
|
||||
return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT);
|
||||
}
|
||||
|
||||
/// perform remote operation
|
||||
CopyMethod copyMethod = null;
|
||||
RemoteOperationResult result = null;
|
||||
try {
|
||||
copyMethod = new CopyMethod(
|
||||
client.getWebdavUri() + WebdavUtils.encodePath(mSrcRemotePath),
|
||||
client.getWebdavUri() + WebdavUtils.encodePath(mTargetRemotePath),
|
||||
mOverwrite
|
||||
);
|
||||
int status = client.executeMethod(copyMethod, COPY_READ_TIMEOUT, COPY_CONNECTION_TIMEOUT);
|
||||
|
||||
/// process response
|
||||
if (status == HttpStatus.SC_MULTI_STATUS) {
|
||||
result = processPartialError(copyMethod);
|
||||
|
||||
} else if (status == HttpStatus.SC_PRECONDITION_FAILED && !mOverwrite) {
|
||||
|
||||
result = new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
|
||||
client.exhaustResponse(copyMethod.getResponseBodyAsStream());
|
||||
|
||||
|
||||
/// for other errors that could be explicitly handled, check first:
|
||||
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
|
||||
|
||||
} else if (status == 400) {
|
||||
result = new RemoteOperationResult(copyMethod.succeeded(),
|
||||
copyMethod.getResponseBodyAsString(), status);
|
||||
} else {
|
||||
result = new RemoteOperationResult(
|
||||
isSuccess(status), // copy.succeeded()? trustful?
|
||||
status,
|
||||
copyMethod.getResponseHeaders()
|
||||
);
|
||||
client.exhaustResponse(copyMethod.getResponseBodyAsStream());
|
||||
}
|
||||
|
||||
Log.i(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " +
|
||||
result.getLogMessage());
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " +
|
||||
result.getLogMessage(), e);
|
||||
|
||||
} finally {
|
||||
if (copyMethod != null)
|
||||
copyMethod.releaseConnection();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Analyzes a multistatus response from the OC server to generate an appropriate result.
|
||||
* <p/>
|
||||
* In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some
|
||||
* children are copied, some other aren't.
|
||||
* <p/>
|
||||
* According to the WebDAV specification, a multistatus response SHOULD NOT include partial
|
||||
* successes (201, 204) nor for descendants of already failed children (424) in the response
|
||||
* entity. But SHOULD NOT != MUST NOT, so take carefully.
|
||||
*
|
||||
* @param copyMethod Copy operation just finished with a multistatus response
|
||||
* @return A result for the {@link com.owncloud.android.lib.resources.files.CopyRemoteFileOperation} caller
|
||||
* @throws java.io.IOException If the response body could not be parsed
|
||||
* @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining
|
||||
* the response XML document fails
|
||||
*/
|
||||
private RemoteOperationResult processPartialError(CopyMethod copyMethod)
|
||||
throws IOException, DavException {
|
||||
// Adding a list of failed descendants to the result could be interesting; or maybe not.
|
||||
// For the moment, let's take the easy way.
|
||||
|
||||
/// check that some error really occurred
|
||||
MultiStatusResponse[] responses = copyMethod.getResponseBodyAsMultiStatus().getResponses();
|
||||
Status[] status;
|
||||
boolean failFound = false;
|
||||
for (int i = 0; i < responses.length && !failFound; i++) {
|
||||
status = responses[i].getStatus();
|
||||
failFound = (
|
||||
status != null &&
|
||||
status.length > 0 &&
|
||||
status[0].getStatusCode() > 299
|
||||
);
|
||||
}
|
||||
|
||||
RemoteOperationResult result;
|
||||
if (failFound) {
|
||||
result = new RemoteOperationResult(ResultCode.PARTIAL_COPY_DONE);
|
||||
} else {
|
||||
result = new RemoteOperationResult(
|
||||
true,
|
||||
HttpStatus.SC_MULTI_STATUS,
|
||||
copyMethod.getResponseHeaders()
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected boolean isSuccess(int status) {
|
||||
return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
package com.owncloud.android.lib.resources.files;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
@@ -33,7 +32,7 @@ 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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
|
||||
/**
|
||||
@@ -58,7 +57,8 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
|
||||
* 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.
|
||||
* @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;
|
||||
@@ -73,7 +73,10 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
boolean noInvalidChars = FileUtils.isValidPath(mRemotePath);
|
||||
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||
boolean versionWithForbiddenChars =
|
||||
(version != null && version.isVersionWithForbiddenCharacters());
|
||||
boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, versionWithForbiddenChars);
|
||||
if (noInvalidChars) {
|
||||
result = createFolder(client);
|
||||
if (!result.isSuccess() && mCreateFullPath &&
|
||||
@@ -98,9 +101,17 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
|
||||
try {
|
||||
mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
|
||||
int status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
|
||||
result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders());
|
||||
Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
|
||||
client.exhaustResponse(mkcol.getResponseBodyAsStream());
|
||||
if ( status == 400 ) {
|
||||
result = new RemoteOperationResult(mkcol.succeeded(),
|
||||
mkcol.getResponseBodyAsString(), status);
|
||||
Log_OC.d(TAG, mkcol.getResponseBodyAsString());
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(mkcol.succeeded(), status,
|
||||
mkcol.getResponseHeaders());
|
||||
Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
|
||||
}
|
||||
client.exhaustResponse(mkcol.getResponseBodyAsStream());
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
|
||||
@@ -61,6 +61,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
|
||||
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
||||
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
||||
private long mModificationTimestamp = 0;
|
||||
private String mEtag = "";
|
||||
private GetMethod mGet;
|
||||
|
||||
private String mRemotePath;
|
||||
@@ -140,12 +141,24 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
|
||||
if (transferred == totalToTransfer) { // Check if the file is completed
|
||||
savedFile = true;
|
||||
Header modificationTime = mGet.getResponseHeader("Last-Modified");
|
||||
if (modificationTime == null) {
|
||||
modificationTime = mGet.getResponseHeader("last-modified");
|
||||
}
|
||||
if (modificationTime != null) {
|
||||
Date d = WebdavUtils.parseResponseDate((String) modificationTime.getValue());
|
||||
mModificationTimestamp = (d != null) ? d.getTime() : 0;
|
||||
}
|
||||
} else {
|
||||
Log_OC.e(TAG, "Could not read modification time from response downloading " + mRemotePath);
|
||||
}
|
||||
|
||||
mEtag = WebdavUtils.getEtagFromResponse(mGet);
|
||||
if (mEtag.length() == 0) {
|
||||
Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath);
|
||||
}
|
||||
|
||||
} else {
|
||||
client.exhaustResponse(mGet.getResponseBodyAsStream());
|
||||
// TODO some kind of error control!
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -190,4 +203,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
|
||||
return mModificationTimestamp;
|
||||
}
|
||||
|
||||
public String getEtag() {
|
||||
return mEtag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.commons.httpclient.methods.HeadMethod;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import com.owncloud.android.lib.common.OwnCloudClient;
|
||||
import com.owncloud.android.lib.common.network.RedirectionPath;
|
||||
import com.owncloud.android.lib.common.network.WebdavUtils;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
@@ -49,35 +49,50 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
||||
private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName();
|
||||
|
||||
private String mPath;
|
||||
private Context mContext;
|
||||
private boolean mSuccessIfAbsent;
|
||||
|
||||
|
||||
/** Sequence of redirections followed. Available only after executing the operation */
|
||||
private RedirectionPath mRedirectionPath = null;
|
||||
// TODO move to {@link RemoteOperation}, that needs a nice refactoring
|
||||
|
||||
/**
|
||||
* Full constructor. Success of the operation will depend upon the value of successIfAbsent.
|
||||
*
|
||||
* @param remotePath Path to append to the URL owned by the client instance.
|
||||
* @param context Android application context.
|
||||
*
|
||||
* @param remotePath Path to append to the URL owned by the client instance.
|
||||
* @param successIfAbsent When 'true', the operation finishes in success if the path does
|
||||
* NOT exist in the remote server (HTTP 404).
|
||||
*/
|
||||
public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) {
|
||||
public ExistenceCheckRemoteOperation(String remotePath, boolean successIfAbsent) {
|
||||
mPath = (remotePath != null) ? remotePath : "";
|
||||
mContext = context;
|
||||
mSuccessIfAbsent = successIfAbsent;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Full constructor. Success of the operation will depend upon the value of successIfAbsent.
|
||||
*
|
||||
* @param remotePath 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).
|
||||
* @deprecated
|
||||
*/
|
||||
public ExistenceCheckRemoteOperation(String remotePath, Context context, boolean successIfAbsent) {
|
||||
this(remotePath, successIfAbsent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
if (!isOnline()) {
|
||||
return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
|
||||
}
|
||||
RemoteOperationResult result = null;
|
||||
HeadMethod head = null;
|
||||
boolean previousFollowRedirects = client.getFollowRedirects();
|
||||
try {
|
||||
head = new HeadMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath));
|
||||
client.setFollowRedirects(false);
|
||||
int status = client.executeMethod(head, TIMEOUT, TIMEOUT);
|
||||
if (previousFollowRedirects) {
|
||||
mRedirectionPath = client.followRedirection(head);
|
||||
status = mRedirectionPath.getLastStatus();
|
||||
}
|
||||
client.exhaustResponse(head.getResponseBodyAsStream());
|
||||
boolean success = (status == HttpStatus.SC_OK && !mSuccessIfAbsent) ||
|
||||
(status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
|
||||
@@ -97,16 +112,25 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
|
||||
} finally {
|
||||
if (head != null)
|
||||
head.releaseConnection();
|
||||
client.setFollowRedirects(previousFollowRedirects);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isOnline() {
|
||||
ConnectivityManager cm = (ConnectivityManager) mContext
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
return cm != null && cm.getActiveNetworkInfo() != null
|
||||
&& cm.getActiveNetworkInfo().isConnectedOrConnecting();
|
||||
|
||||
/**
|
||||
* Gets the sequence of redirections followed during the execution of the operation.
|
||||
*
|
||||
* @return Sequence of redirections followed, if any, or NULL if the operation was not executed.
|
||||
*/
|
||||
public RedirectionPath getRedirectionPath() {
|
||||
return mRedirectionPath;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return 'True' if the operation was executed and at least one redirection was followed.
|
||||
*/
|
||||
public boolean wasRedirected() {
|
||||
return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,12 @@ package com.owncloud.android.lib.resources.files;
|
||||
import java.io.File;
|
||||
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
private static final String TAG = FileUtils.class.getSimpleName();
|
||||
|
||||
public static final String PATH_SEPARATOR = "/";
|
||||
|
||||
|
||||
@@ -40,39 +43,44 @@ public class FileUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the fileName to detect if contains any forbidden character: / , \ , < , > , : , " , | , ? , *
|
||||
* Validate the fileName to detect if contains any forbidden character: / , \ , < , > ,
|
||||
* : , " , | , ? , *
|
||||
* @param fileName
|
||||
* @param versionSupportsForbiddenChars
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidName(String fileName) {
|
||||
public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) {
|
||||
boolean result = true;
|
||||
|
||||
Log_OC.d("FileUtils", "fileName =======" + fileName);
|
||||
if (fileName.contains(PATH_SEPARATOR) ||
|
||||
Log_OC.d(TAG, "fileName =======" + fileName);
|
||||
if ( (versionSupportsForbiddenChars && fileName.contains(PATH_SEPARATOR)) ||
|
||||
(!versionSupportsForbiddenChars && ( fileName.contains(PATH_SEPARATOR) ||
|
||||
fileName.contains("\\") || fileName.contains("<") || fileName.contains(">") ||
|
||||
fileName.contains(":") || fileName.contains("\"") || 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: \ , < , > , : , " , | , ? , *
|
||||
* Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | ,
|
||||
* ? , *
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidPath(String path) {
|
||||
public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) {
|
||||
boolean result = true;
|
||||
|
||||
Log_OC.d("FileUtils", "path ....... " + path);
|
||||
if (path.contains("\\") || path.contains("<") || path.contains(">") ||
|
||||
Log_OC.d(TAG, "path ....... " + path);
|
||||
if (!versionSupportsForbidenChars &&
|
||||
(path.contains("\\") || path.contains("<") || path.contains(">") ||
|
||||
path.contains(":") || path.contains("\"") || path.contains("|") ||
|
||||
path.contains("?") || path.contains("*")) {
|
||||
path.contains("?") || path.contains("*") ) ){
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ 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;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
|
||||
/**
|
||||
@@ -87,9 +88,13 @@ public class MoveRemoteFileOperation extends RemoteOperation {
|
||||
*/
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
|
||||
|
||||
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||
boolean versionWithForbiddenChars =
|
||||
(version != null && version.isVersionWithForbiddenCharacters());
|
||||
|
||||
/// check parameters
|
||||
if (!FileUtils.isValidPath(mTargetRemotePath)) {
|
||||
if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) {
|
||||
return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
|
||||
}
|
||||
|
||||
@@ -128,15 +133,17 @@ public class MoveRemoteFileOperation extends RemoteOperation {
|
||||
/// for other errors that could be explicitly handled, check first:
|
||||
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
|
||||
|
||||
} else {
|
||||
|
||||
result = new RemoteOperationResult(
|
||||
isSuccess(status), // move.succeeded()? trustful?
|
||||
status,
|
||||
move.getResponseHeaders()
|
||||
);
|
||||
client.exhaustResponse(move.getResponseBodyAsStream());
|
||||
}
|
||||
} else if (status == 400) {
|
||||
result = new RemoteOperationResult(move.succeeded(),
|
||||
move.getResponseBodyAsString(), status);
|
||||
} else {
|
||||
result = new RemoteOperationResult(
|
||||
isSuccess(status), // move.succeeded()? trustful?
|
||||
status,
|
||||
move.getResponseHeaders()
|
||||
);
|
||||
client.exhaustResponse(move.getResponseBodyAsStream());
|
||||
}
|
||||
|
||||
Log.i(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " +
|
||||
result.getLogMessage());
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
package com.owncloud.android.lib.resources.files;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@@ -51,8 +52,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||
private String mPermissions;
|
||||
private String mRemoteId;
|
||||
private long mSize;
|
||||
private long mQuotaUsedBytes;
|
||||
private long mQuotaAvailableBytes;
|
||||
private BigDecimal mQuotaUsedBytes;
|
||||
private BigDecimal mQuotaAvailableBytes;
|
||||
|
||||
/**
|
||||
* Getters and Setters
|
||||
@@ -130,11 +131,11 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
public void setQuotaUsedBytes (long quotaUsedBytes) {
|
||||
public void setQuotaUsedBytes (BigDecimal quotaUsedBytes) {
|
||||
mQuotaUsedBytes = quotaUsedBytes;
|
||||
}
|
||||
|
||||
public void setQuotaAvailableBytes (long quotaAvailableBytes) {
|
||||
public void setQuotaAvailableBytes (BigDecimal quotaAvailableBytes) {
|
||||
mQuotaAvailableBytes = quotaAvailableBytes;
|
||||
}
|
||||
|
||||
@@ -184,8 +185,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||
mPermissions = null;
|
||||
mRemoteId = null;
|
||||
mSize = 0;
|
||||
mQuotaUsedBytes = 0;
|
||||
mQuotaAvailableBytes = 0;
|
||||
mQuotaUsedBytes = null;
|
||||
mQuotaAvailableBytes = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,8 +224,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||
mPermissions= source.readString();
|
||||
mRemoteId = source.readString();
|
||||
mSize = source.readLong();
|
||||
mQuotaUsedBytes = source.readLong();
|
||||
mQuotaAvailableBytes = source.readLong();
|
||||
mQuotaUsedBytes = (BigDecimal) source.readSerializable();
|
||||
mQuotaAvailableBytes = (BigDecimal) source.readSerializable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -243,8 +244,8 @@ public class RemoteFile implements Parcelable, Serializable {
|
||||
dest.writeString(mPermissions);
|
||||
dest.writeString(mRemoteId);
|
||||
dest.writeLong(mSize);
|
||||
dest.writeLong(mQuotaUsedBytes);
|
||||
dest.writeLong(mQuotaAvailableBytes);
|
||||
dest.writeSerializable(mQuotaUsedBytes);
|
||||
dest.writeSerializable(mQuotaAvailableBytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ 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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
|
||||
/**
|
||||
@@ -88,42 +89,52 @@ public class RenameRemoteFileOperation extends RemoteOperation {
|
||||
RemoteOperationResult result = null;
|
||||
|
||||
LocalMoveMethod move = null;
|
||||
|
||||
boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath);
|
||||
|
||||
OwnCloudVersion version = client.getOwnCloudVersion();
|
||||
boolean versionWithForbiddenChars =
|
||||
(version != null && version.isVersionWithForbiddenCharacters());
|
||||
boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars);
|
||||
|
||||
if (noInvalidChars) {
|
||||
try {
|
||||
|
||||
if (mNewName.equals(mOldName)) {
|
||||
return new RemoteOperationResult(ResultCode.OK);
|
||||
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);
|
||||
|
||||
if (status == 400) {
|
||||
result = new RemoteOperationResult(move.succeeded(),
|
||||
move.getResponseBodyAsString(), status);
|
||||
Log_OC.d(TAG, move.getResponseBodyAsString());
|
||||
} else {
|
||||
client.exhaustResponse(move.getResponseBodyAsStream());//exhaust response,
|
||||
// although not interesting
|
||||
result = new RemoteOperationResult(move.succeeded(), status,
|
||||
move.getResponseHeaders());
|
||||
Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " +
|
||||
result.getLogMessage());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " +
|
||||
((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " +
|
||||
result.getLogMessage(), e);
|
||||
|
||||
} finally {
|
||||
if (move != null)
|
||||
move.releaseConnection();
|
||||
}
|
||||
|
||||
|
||||
// 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_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " +
|
||||
result.getLogMessage());
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log_OC.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);
|
||||
}
|
||||
|
||||
@@ -24,13 +24,14 @@
|
||||
|
||||
package com.owncloud.android.lib.resources.files;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
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;
|
||||
@@ -40,9 +41,11 @@ 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.InvalidCharacterExceptionParser;
|
||||
import com.owncloud.android.lib.common.operations.OperationCancelledException;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
/**
|
||||
* Remote operation performing the upload of a remote file to the ownCloud server.
|
||||
@@ -53,13 +56,19 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
|
||||
public class UploadRemoteFileOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = UploadRemoteFileOperation.class.getSimpleName();
|
||||
|
||||
protected static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length";
|
||||
protected static final String IF_MATCH_HEADER = "If-Match";
|
||||
|
||||
protected String mLocalPath;
|
||||
protected String mRemotePath;
|
||||
protected String mMimeType;
|
||||
protected PutMethod mPutMethod = null;
|
||||
protected boolean mForbiddenCharsInServer = false;
|
||||
protected String mRequiredEtag = null;
|
||||
|
||||
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
||||
protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
||||
protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
||||
|
||||
protected RequestEntity mEntity = null;
|
||||
@@ -67,7 +76,12 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
||||
public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType) {
|
||||
mLocalPath = localPath;
|
||||
mRemotePath = remotePath;
|
||||
mMimeType = mimeType;
|
||||
mMimeType = mimeType;
|
||||
}
|
||||
|
||||
public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType, String requiredEtag) {
|
||||
this(localPath, remotePath, mimeType);
|
||||
mRequiredEtag = requiredEtag;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,25 +89,28 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
||||
RemoteOperationResult result = null;
|
||||
|
||||
try {
|
||||
// / perform the upload
|
||||
synchronized (mCancellationRequested) {
|
||||
if (mCancellationRequested.get()) {
|
||||
throw new OperationCancelledException();
|
||||
mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
|
||||
|
||||
if (mCancellationRequested.get()) {
|
||||
// the operation was cancelled before getting it's turn to be executed in the queue of uploads
|
||||
result = new RemoteOperationResult(new OperationCancelledException());
|
||||
|
||||
} else {
|
||||
// perform the upload
|
||||
int status = uploadFile(client);
|
||||
if (mForbiddenCharsInServer){
|
||||
result = new RemoteOperationResult(
|
||||
RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER);
|
||||
} else {
|
||||
mPutMethod = new PutMethod(client.getWebdavUri() +
|
||||
WebdavUtils.encodePath(mRemotePath));
|
||||
result = new RemoteOperationResult(isSuccess(status), status,
|
||||
(mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
if (mPutMethod != null && mPutMethod.isAborted()) {
|
||||
result = new RemoteOperationResult(new OperationCancelledException());
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(e);
|
||||
}
|
||||
@@ -106,8 +123,7 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
||||
status == HttpStatus.SC_NO_CONTENT));
|
||||
}
|
||||
|
||||
protected int uploadFile(OwnCloudClient client) throws HttpException, IOException,
|
||||
OperationCancelledException {
|
||||
protected int uploadFile(OwnCloudClient client) throws IOException {
|
||||
int status = -1;
|
||||
try {
|
||||
File f = new File(mLocalPath);
|
||||
@@ -116,8 +132,26 @@ public class UploadRemoteFileOperation extends RemoteOperation {
|
||||
((ProgressiveDataTransferer)mEntity)
|
||||
.addDatatransferProgressListeners(mDataTransferListeners);
|
||||
}
|
||||
if (mRequiredEtag != null && mRequiredEtag.length() > 0) {
|
||||
mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\"");
|
||||
}
|
||||
mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length()));
|
||||
mPutMethod.setRequestEntity(mEntity);
|
||||
status = client.executeMethod(mPutMethod);
|
||||
|
||||
if (status == 400) {
|
||||
InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser();
|
||||
InputStream is = new ByteArrayInputStream(
|
||||
mPutMethod.getResponseBodyAsString().getBytes());
|
||||
try {
|
||||
mForbiddenCharsInServer = xmlParser.parseXMLResponse(is);
|
||||
|
||||
} catch (Exception e) {
|
||||
mForbiddenCharsInServer = false;
|
||||
Log_OC.e(TAG, "Exception reading exception from server", e);
|
||||
}
|
||||
}
|
||||
|
||||
client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
|
||||
|
||||
} finally {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author masensio
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -24,24 +26,16 @@
|
||||
|
||||
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 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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
/**
|
||||
* Creates a new share. This allows sharing with a user or group or as a link.
|
||||
*
|
||||
* @author masensio
|
||||
*
|
||||
*/
|
||||
public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
|
||||
@@ -54,20 +48,20 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
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 mRemoteFilePath;
|
||||
private ShareType mShareType;
|
||||
private String mShareWith;
|
||||
private boolean mPublicUpload;
|
||||
private String mPassword;
|
||||
private int mPermissions;
|
||||
private boolean mGetShareDetails;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param remoteFilePath 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 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
|
||||
@@ -81,8 +75,14 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
* To obtain combinations, add the desired values together.
|
||||
* For instance, for Re-Share, delete, read, update, add 16+8+2+1 = 27.
|
||||
*/
|
||||
public CreateRemoteShareOperation(String remoteFilePath, ShareType shareType, String shareWith, boolean publicUpload,
|
||||
String password, int permissions) {
|
||||
public CreateRemoteShareOperation(
|
||||
String remoteFilePath,
|
||||
ShareType shareType,
|
||||
String shareWith,
|
||||
boolean publicUpload,
|
||||
String password,
|
||||
int permissions
|
||||
) {
|
||||
|
||||
mRemoteFilePath = remoteFilePath;
|
||||
mShareType = shareType;
|
||||
@@ -90,6 +90,15 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
mPublicUpload = publicUpload;
|
||||
mPassword = password;
|
||||
mPermissions = permissions;
|
||||
mGetShareDetails = false; // defaults to false for backwards compatibility
|
||||
}
|
||||
|
||||
public boolean isGettingShareDetails () {
|
||||
return mGetShareDetails;
|
||||
}
|
||||
|
||||
public void setGetShareDetails(boolean set) {
|
||||
mGetShareDetails = set;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,7 +111,6 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
try {
|
||||
// Post Method
|
||||
post = new PostMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
||||
//Log_OC.d(TAG, "URL ------> " + client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
||||
|
||||
post.setRequestHeader( "Content-Type",
|
||||
"application/x-www-form-urlencoded; charset=utf-8"); // necessary for special characters
|
||||
@@ -110,11 +118,15 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
post.addParameter(PARAM_PATH, mRemoteFilePath);
|
||||
post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue()));
|
||||
post.addParameter(PARAM_SHARE_WITH, mShareWith);
|
||||
post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload));
|
||||
if (mPublicUpload) {
|
||||
post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(true));
|
||||
}
|
||||
if (mPassword != null && mPassword.length() > 0) {
|
||||
post.addParameter(PARAM_PASSWORD, mPassword);
|
||||
}
|
||||
post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions));
|
||||
if (OCShare.DEFAULT_PERMISSION != mPermissions) {
|
||||
post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions));
|
||||
}
|
||||
|
||||
post.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
@@ -123,31 +135,21 @@ public class CreateRemoteShareOperation extends RemoteOperation {
|
||||
if(isSuccess(status)) {
|
||||
String response = post.getResponseBodyAsString();
|
||||
|
||||
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_OC.d(TAG, "Created " + mShares.size() + " share(s)");
|
||||
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.SHARE_NOT_FOUND);
|
||||
|
||||
} else if (xmlParser.isFailure()) {
|
||||
result = new RemoteOperationResult(ResultCode.SHARE_FORBIDDEN);
|
||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||
new ShareXMLParser()
|
||||
);
|
||||
parser.setOneOrMoreSharesRequired(true);
|
||||
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||
parser.setServerBaseUri(client.getBaseUri());
|
||||
result = parser.parse(response);
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, post.getResponseHeaders());
|
||||
if (result.isSuccess() && mGetShareDetails) {
|
||||
// retrieve more info - POST only returns the index of the new share
|
||||
OCShare emptyShare = (OCShare) result.getData().get(0);
|
||||
GetRemoteShareOperation getInfo = new GetRemoteShareOperation(
|
||||
emptyShare.getRemoteId()
|
||||
);
|
||||
result = getInfo.execute(client);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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 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.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
/**
|
||||
* Get the data about a Share resource, known its remote ID.
|
||||
*/
|
||||
|
||||
public class GetRemoteShareOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = GetRemoteShareOperation.class.getSimpleName();
|
||||
|
||||
private long mRemoteId;
|
||||
|
||||
|
||||
public GetRemoteShareOperation(long remoteId) {
|
||||
mRemoteId = remoteId;
|
||||
}
|
||||
|
||||
|
||||
@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.SHARING_API_PATH + "/" + Long.toString(mRemoteId));
|
||||
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
status = client.executeMethod(get);
|
||||
|
||||
if(isSuccess(status)) {
|
||||
String response = get.getResponseBodyAsString();
|
||||
|
||||
// Parse xml response and obtain the list of shares
|
||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||
new ShareXMLParser()
|
||||
);
|
||||
parser.setOneOrMoreSharesRequired(true);
|
||||
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||
parser.setServerBaseUri(client.getBaseUri());
|
||||
result = parser.parse(response);
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log_OC.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,199 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
*
|
||||
* @author masensio
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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 android.net.Uri;
|
||||
|
||||
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.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by masensio on 08/10/2015.
|
||||
*
|
||||
* Retrieves a list of sharees (possible targets of a share) from the ownCloud server.
|
||||
*
|
||||
* Currently only handles users and groups. Users in other OC servers (federation) should be added later.
|
||||
*
|
||||
* Depends on SHAREE API. {@See https://github.com/owncloud/documentation/issues/1626}
|
||||
*
|
||||
* Syntax:
|
||||
* Entry point: ocs/v2.php/apps/files_sharing/api/v1/sharees
|
||||
* HTTP method: GET
|
||||
* url argument: itemType - string, required
|
||||
* url argument: format - string, optional
|
||||
* url argument: search - string, optional
|
||||
* url arguments: perPage - int, optional
|
||||
* url arguments: page - int, optional
|
||||
*
|
||||
* Status codes:
|
||||
* 100 - successful
|
||||
*/
|
||||
public class GetRemoteShareesOperation extends RemoteOperation{
|
||||
|
||||
private static final String TAG = GetRemoteShareesOperation.class.getSimpleName();
|
||||
|
||||
// OCS Routes
|
||||
private static final String OCS_ROUTE = "ocs/v2.php/apps/files_sharing/api/v1/sharees"; // from OC 8.2
|
||||
|
||||
// Arguments - names
|
||||
private static final String PARAM_FORMAT = "format";
|
||||
private static final String PARAM_ITEM_TYPE = "itemType";
|
||||
private static final String PARAM_SEARCH = "search";
|
||||
private static final String PARAM_PAGE = "page"; // default = 1
|
||||
private static final String PARAM_PER_PAGE = "perPage"; // default = 200
|
||||
|
||||
// Arguments - constant values
|
||||
private static final String VALUE_FORMAT = "json";
|
||||
private static final String VALUE_ITEM_TYPE = "search"; // to get the server search for users / groups
|
||||
|
||||
|
||||
// JSON Node names
|
||||
private static final String NODE_OCS = "ocs";
|
||||
private static final String NODE_DATA = "data";
|
||||
private static final String NODE_EXACT = "exact";
|
||||
private static final String NODE_USERS = "users";
|
||||
private static final String NODE_GROUPS = "groups";
|
||||
public static final String NODE_VALUE = "value";
|
||||
public static final String PROPERTY_LABEL = "label";
|
||||
public static final String PROPERTY_SHARE_TYPE = "shareType";
|
||||
public static final String PROPERTY_SHARE_WITH = "shareWith";
|
||||
|
||||
// Result types
|
||||
public static final Byte USER_TYPE = 0;
|
||||
public static final Byte GROUP_TYPE = 1;
|
||||
|
||||
private String mSearchString;
|
||||
private int mPage;
|
||||
private int mPerPage;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param searchString string for searching users, optional
|
||||
* @param page page index in the list of results; beginning in 1
|
||||
* @param perPage maximum number of results in a single page
|
||||
*/
|
||||
public GetRemoteShareesOperation(String searchString, int page, int perPage) {
|
||||
mSearchString = searchString;
|
||||
mPage = page;
|
||||
mPerPage = perPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
int status;
|
||||
GetMethod get = null;
|
||||
|
||||
try{
|
||||
Uri requestUri = client.getBaseUri();
|
||||
Uri.Builder uriBuilder = requestUri.buildUpon();
|
||||
uriBuilder.appendEncodedPath(OCS_ROUTE);
|
||||
uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT);
|
||||
uriBuilder.appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE);
|
||||
uriBuilder.appendQueryParameter(PARAM_SEARCH, mSearchString);
|
||||
uriBuilder.appendQueryParameter(PARAM_PAGE, String.valueOf(mPage));
|
||||
uriBuilder.appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage));
|
||||
|
||||
// Get Method
|
||||
get = new GetMethod(uriBuilder.build().toString());
|
||||
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
status = client.executeMethod(get);
|
||||
|
||||
if(isSuccess(status)) {
|
||||
String response = get.getResponseBodyAsString();
|
||||
Log_OC.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);
|
||||
JSONObject respExact = respData.getJSONObject(NODE_EXACT);
|
||||
JSONArray respExactUsers = respExact.getJSONArray(NODE_USERS);
|
||||
JSONArray respExactGroups = respExact.getJSONArray(NODE_GROUPS);
|
||||
JSONArray respPartialUsers = respData.getJSONArray(NODE_USERS);
|
||||
JSONArray respPartialGroups = respData.getJSONArray(NODE_GROUPS);
|
||||
JSONArray[] jsonResults = {
|
||||
respExactUsers,
|
||||
respExactGroups,
|
||||
respPartialUsers,
|
||||
respPartialGroups
|
||||
};
|
||||
|
||||
ArrayList<Object> data = new ArrayList<Object>(); // For result data
|
||||
for (int i=0; i<4; i++) {
|
||||
for(int j=0; j< jsonResults[i].length(); j++){
|
||||
JSONObject jsonResult = jsonResults[i].getJSONObject(j);
|
||||
data.add(jsonResult);
|
||||
Log_OC.d(TAG, "*** Added item: " + jsonResult.getString(PROPERTY_LABEL));
|
||||
}
|
||||
}
|
||||
|
||||
// Result
|
||||
result = new RemoteOperationResult(true, status, get.getResponseHeaders());
|
||||
result.setData(data);
|
||||
|
||||
Log_OC.d(TAG, "*** Get Users or groups completed " );
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
|
||||
String response = get.getResponseBodyAsString();
|
||||
Log_OC.e(TAG, "Failed response while getting users/groups from the server ");
|
||||
if (response != null) {
|
||||
Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response);
|
||||
} else {
|
||||
Log_OC.e(TAG, "*** status code: " + status);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log_OC.e(TAG, "Exception while getting users/groups", e);
|
||||
|
||||
} finally {
|
||||
if (get != null) {
|
||||
get.releaseConnection();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isSuccess(int status) {
|
||||
return (status == HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
+25
-41
@@ -1,4 +1,6 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author masensio
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -24,10 +26,6 @@
|
||||
|
||||
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;
|
||||
@@ -35,18 +33,13 @@ 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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
/**
|
||||
* 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 GetRemoteSharesForFileOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = GetRemoteSharesForFileOperation.class.getSimpleName();
|
||||
@@ -55,8 +48,6 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
||||
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 mRemoteFilePath;
|
||||
private boolean mReshares;
|
||||
private boolean mSubfiles;
|
||||
@@ -64,13 +55,15 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param remoteFilePath 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.
|
||||
* @param remoteFilePath Path to file or folder
|
||||
* @param reshares If set to false (default), only shares owned by the current user are
|
||||
* returned.
|
||||
* If set to true, shares owned by any user 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 GetRemoteSharesForFileOperation(String remoteFilePath, boolean reshares, boolean subfiles) {
|
||||
public GetRemoteSharesForFileOperation(String remoteFilePath, boolean reshares,
|
||||
boolean subfiles) {
|
||||
mRemoteFilePath = remoteFilePath;
|
||||
mReshares = reshares;
|
||||
mSubfiles = subfiles;
|
||||
@@ -88,11 +81,11 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
||||
get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
||||
|
||||
// Add Parameters to Get Method
|
||||
get.setQueryString(new NameValuePair[] {
|
||||
new NameValuePair(PARAM_PATH, mRemoteFilePath),
|
||||
new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)),
|
||||
new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles))
|
||||
});
|
||||
get.setQueryString(new NameValuePair[]{
|
||||
new NameValuePair(PARAM_PATH, mRemoteFilePath),
|
||||
new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)),
|
||||
new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles))
|
||||
});
|
||||
|
||||
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
@@ -101,25 +94,16 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
|
||||
if(isSuccess(status)) {
|
||||
String response = get.getResponseBodyAsString();
|
||||
|
||||
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_OC.d(TAG, "Got " + mShares.size() + " shares");
|
||||
result = new RemoteOperationResult(ResultCode.OK);
|
||||
ArrayList<Object> sharesObjects = new ArrayList<Object>();
|
||||
for (OCShare share: mShares) {
|
||||
// Build the link
|
||||
if (share.getToken().length() > 0) {
|
||||
share.setShareLink(client.getBaseUri() + ShareUtils.SHARING_LINK_TOKEN + share.getToken());
|
||||
}
|
||||
sharesObjects.add(share);
|
||||
}
|
||||
result.setData(sharesObjects);
|
||||
// Parse xml response and obtain the list of shares
|
||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||
new ShareXMLParser()
|
||||
);
|
||||
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||
parser.setServerBaseUri(client.getBaseUri());
|
||||
result = parser.parse(response);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
Log_OC.d(TAG, "Got " + result.getData().size() + " shares");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author masensio
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -24,34 +26,24 @@
|
||||
|
||||
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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
|
||||
/**
|
||||
* Get the data from the server to know shares
|
||||
* Get the data from the server about ALL the known shares owned by the requester.
|
||||
*
|
||||
* @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() {
|
||||
}
|
||||
|
||||
@@ -68,23 +60,17 @@ public class GetRemoteSharesOperation extends RemoteOperation {
|
||||
get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
|
||||
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
status = client.executeMethod(get);
|
||||
|
||||
if(isSuccess(status)) {
|
||||
String response = get.getResponseBodyAsString();
|
||||
|
||||
// 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_OC.d(TAG, "Got " + mShares.size() + " shares");
|
||||
result = new RemoteOperationResult(ResultCode.OK);
|
||||
ArrayList<Object> sharesObjects = new ArrayList<Object>();
|
||||
for (OCShare share: mShares) {
|
||||
sharesObjects.add(share);
|
||||
}
|
||||
result.setData(sharesObjects);
|
||||
}
|
||||
// Parse xml response and obtain the list of shares
|
||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||
new ShareXMLParser()
|
||||
);
|
||||
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||
parser.setServerBaseUri(client.getBaseUri());
|
||||
result = parser.parse(response);
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
|
||||
}
|
||||
|
||||
@@ -45,7 +45,24 @@ public class OCShare implements Parcelable, Serializable {
|
||||
private static final long serialVersionUID = 4124975224281327921L;
|
||||
|
||||
private static final String TAG = OCShare.class.getSimpleName();
|
||||
|
||||
|
||||
public static final int DEFAULT_PERMISSION = -1;
|
||||
public static final int READ_PERMISSION_FLAG = 1;
|
||||
public static final int UPDATE_PERMISSION_FLAG = 2;
|
||||
public static final int CREATE_PERMISSION_FLAG = 4;
|
||||
public static final int DELETE_PERMISSION_FLAG = 8;
|
||||
public static final int SHARE_PERMISSION_FLAG = 16;
|
||||
public static final int MAXIMUM_PERMISSIONS_FOR_FILE =
|
||||
READ_PERMISSION_FLAG +
|
||||
UPDATE_PERMISSION_FLAG +
|
||||
SHARE_PERMISSION_FLAG
|
||||
;
|
||||
public static final int MAXIMUM_PERMISSIONS_FOR_FOLDER =
|
||||
MAXIMUM_PERMISSIONS_FOR_FILE +
|
||||
CREATE_PERMISSION_FLAG +
|
||||
DELETE_PERMISSION_FLAG
|
||||
;
|
||||
|
||||
private long mId;
|
||||
private long mFileSource;
|
||||
private long mItemSource;
|
||||
@@ -59,7 +76,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
private String mSharedWithDisplayName;
|
||||
private boolean mIsFolder;
|
||||
private long mUserId;
|
||||
private long mIdRemoteShared;
|
||||
private long mRemoteId;
|
||||
private String mShareLink;
|
||||
|
||||
public OCShare() {
|
||||
@@ -84,17 +101,17 @@ public class OCShare implements Parcelable, Serializable {
|
||||
mFileSource = 0;
|
||||
mItemSource = 0;
|
||||
mShareType = ShareType.NO_SHARED;
|
||||
mShareWith = null;
|
||||
mPath = null;
|
||||
mShareWith = "";
|
||||
mPath = "";
|
||||
mPermissions = -1;
|
||||
mSharedDate = 0;
|
||||
mExpirationDate = 0;
|
||||
mToken = null;
|
||||
mSharedWithDisplayName = null;
|
||||
mToken = "";
|
||||
mSharedWithDisplayName = "";
|
||||
mIsFolder = false;
|
||||
mUserId = -1;
|
||||
mIdRemoteShared = -1;
|
||||
mShareLink = null;
|
||||
mRemoteId = -1;
|
||||
mShareLink = "";
|
||||
}
|
||||
|
||||
/// Getters and Setters
|
||||
@@ -136,7 +153,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
}
|
||||
|
||||
public void setShareWith(String shareWith) {
|
||||
this.mShareWith = shareWith;
|
||||
this.mShareWith = (shareWith != null) ? shareWith : "";
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
@@ -144,7 +161,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.mPath = path;
|
||||
this.mPath = (path != null) ? path : "";
|
||||
}
|
||||
|
||||
public int getPermissions() {
|
||||
@@ -176,7 +193,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.mToken = token;
|
||||
this.mToken = (token != null) ? token : "";
|
||||
}
|
||||
|
||||
public String getSharedWithDisplayName() {
|
||||
@@ -184,7 +201,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
}
|
||||
|
||||
public void setSharedWithDisplayName(String sharedWithDisplayName) {
|
||||
this.mSharedWithDisplayName = sharedWithDisplayName;
|
||||
this.mSharedWithDisplayName = (sharedWithDisplayName != null) ? sharedWithDisplayName : "";
|
||||
}
|
||||
|
||||
public boolean isFolder() {
|
||||
@@ -203,12 +220,12 @@ public class OCShare implements Parcelable, Serializable {
|
||||
this.mUserId = userId;
|
||||
}
|
||||
|
||||
public long getIdRemoteShared() {
|
||||
return mIdRemoteShared;
|
||||
public long getRemoteId() {
|
||||
return mRemoteId;
|
||||
}
|
||||
|
||||
public void setIdRemoteShared(long idRemoteShared) {
|
||||
this.mIdRemoteShared = idRemoteShared;
|
||||
public void setIdRemoteShared(long remoteId) {
|
||||
this.mRemoteId = remoteId;
|
||||
}
|
||||
|
||||
public String getShareLink() {
|
||||
@@ -216,7 +233,11 @@ public class OCShare implements Parcelable, Serializable {
|
||||
}
|
||||
|
||||
public void setShareLink(String shareLink) {
|
||||
this.mShareLink = shareLink;
|
||||
this.mShareLink = (shareLink != null) ? shareLink : "";
|
||||
}
|
||||
|
||||
public boolean isPasswordProtected() {
|
||||
return ShareType.PUBLIC_LINK.equals(mShareType) && mShareWith.length() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,7 +283,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
mSharedWithDisplayName = source.readString();
|
||||
mIsFolder = source.readInt() == 0;
|
||||
mUserId = source.readLong();
|
||||
mIdRemoteShared = source.readLong();
|
||||
mRemoteId = source.readLong();
|
||||
mShareLink = source.readString();
|
||||
}
|
||||
|
||||
@@ -288,7 +309,7 @@ public class OCShare implements Parcelable, Serializable {
|
||||
dest.writeString(mSharedWithDisplayName);
|
||||
dest.writeInt(mIsFolder ? 1 : 0);
|
||||
dest.writeLong(mUserId);
|
||||
dest.writeLong(mIdRemoteShared);
|
||||
dest.writeLong(mRemoteId);
|
||||
dest.writeString(mShareLink);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author masensio
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -24,23 +26,16 @@
|
||||
|
||||
package com.owncloud.android.lib.resources.shares;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.httpclient.HttpStatus;
|
||||
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
|
||||
|
||||
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 com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
/**
|
||||
* Remove a share
|
||||
*
|
||||
* @author masensio
|
||||
*
|
||||
*/
|
||||
|
||||
public class RemoveRemoteShareOperation extends RemoteOperation {
|
||||
@@ -72,28 +67,20 @@ public class RemoveRemoteShareOperation extends RemoteOperation {
|
||||
delete = new DeleteMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + id);
|
||||
|
||||
delete.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
|
||||
status = client.executeMethod(delete);
|
||||
|
||||
if(isSuccess(status)) {
|
||||
String response = delete.getResponseBodyAsString();
|
||||
|
||||
result = new RemoteOperationResult(ResultCode.OK);
|
||||
|
||||
// Parse xml response
|
||||
// convert String into InputStream
|
||||
InputStream is = new ByteArrayInputStream(response.getBytes());
|
||||
ShareXMLParser xmlParser = new ShareXMLParser();
|
||||
xmlParser.parseXMLResponse(is);
|
||||
if (xmlParser.isSuccess()) {
|
||||
result = new RemoteOperationResult(ResultCode.OK);
|
||||
} else if (xmlParser.isFileNotFound()){
|
||||
result = new RemoteOperationResult(ResultCode.SHARE_NOT_FOUND);
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, delete.getResponseHeaders());
|
||||
}
|
||||
|
||||
// Parse xml response and obtain the list of shares
|
||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||
new ShareXMLParser()
|
||||
);
|
||||
result = parser.parse(response);
|
||||
|
||||
Log_OC.d(TAG, "Unshare " + id + ": " + result.getLogMessage());
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, delete.getResponseHeaders());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
/**
|
||||
* Provides method to define a set of share permissions and calculate the appropiate
|
||||
* int value representing it.
|
||||
*/
|
||||
public class SharePermissionsBuilder {
|
||||
|
||||
/** Set of permissions */
|
||||
private int mPermissions = OCShare.READ_PERMISSION_FLAG; // READ is minimum permission
|
||||
|
||||
/**
|
||||
* Sets or clears permission to reshare a file or folder.
|
||||
*
|
||||
* @param enabled 'True' to set, 'false' to clear.
|
||||
* @return Instance to builder itself, to allow consecutive calls to setters
|
||||
*/
|
||||
public SharePermissionsBuilder setSharePermission(boolean enabled) {
|
||||
updatePermission(OCShare.SHARE_PERMISSION_FLAG, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or clears permission to update a folder or folder.
|
||||
*
|
||||
* @param enabled 'True' to set, 'false' to clear.
|
||||
* @return Instance to builder itself, to allow consecutive calls to setters
|
||||
*/
|
||||
public SharePermissionsBuilder setUpdatePermission(boolean enabled) {
|
||||
updatePermission(OCShare.UPDATE_PERMISSION_FLAG, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or clears permission to create files in share folder.
|
||||
*
|
||||
* @param enabled 'True' to set, 'false' to clear.
|
||||
* @return Instance to builder itself, to allow consecutive calls to setters
|
||||
*/
|
||||
public SharePermissionsBuilder setCreatePermission(boolean enabled) {
|
||||
updatePermission(OCShare.CREATE_PERMISSION_FLAG, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or clears permission to delete files in a shared folder.
|
||||
*
|
||||
* @param enabled 'True' to set, 'false' to clear.
|
||||
* @return Instance to builder itself, to allow consecutive calls to setters
|
||||
*/
|
||||
public SharePermissionsBuilder setDeletePermission(boolean enabled) {
|
||||
updatePermission(OCShare.DELETE_PERMISSION_FLAG, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common code to update the value of the set of permissions.
|
||||
*
|
||||
* @param permissionsFlag Flag for the permission to update.
|
||||
* @param enable 'True' to set, 'false' to clear.
|
||||
*/
|
||||
private void updatePermission(int permissionsFlag, boolean enable) {
|
||||
if (enable) {
|
||||
// add permission
|
||||
mPermissions |= permissionsFlag;
|
||||
} else {
|
||||
// delete permission
|
||||
mPermissions &= ~permissionsFlag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Builds' the int value for the accumulated set of permissions.
|
||||
*
|
||||
* @return An int value representing the accumulated set of permissions.
|
||||
*/
|
||||
public int build() {
|
||||
return mPermissions;
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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 android.net.Uri;
|
||||
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ShareToRemoteOperationResultParser {
|
||||
|
||||
private static final String TAG = ShareToRemoteOperationResultParser.class.getSimpleName();
|
||||
|
||||
private ShareXMLParser mShareXmlParser = null;
|
||||
private boolean mOneOrMoreSharesRequired = false;
|
||||
private OwnCloudVersion mOwnCloudVersion = null;
|
||||
private Uri mServerBaseUri = null;
|
||||
|
||||
|
||||
public ShareToRemoteOperationResultParser(ShareXMLParser shareXmlParser) {
|
||||
mShareXmlParser = shareXmlParser;
|
||||
}
|
||||
|
||||
public void setOneOrMoreSharesRequired(boolean oneOrMoreSharesRequired) {
|
||||
mOneOrMoreSharesRequired = oneOrMoreSharesRequired;
|
||||
}
|
||||
|
||||
public void setOwnCloudVersion(OwnCloudVersion ownCloudVersion) {
|
||||
mOwnCloudVersion = ownCloudVersion;
|
||||
}
|
||||
|
||||
public void setServerBaseUri(Uri serverBaseURi) {
|
||||
mServerBaseUri = serverBaseURi;
|
||||
}
|
||||
|
||||
public RemoteOperationResult parse(String serverResponse) {
|
||||
if (serverResponse == null || serverResponse.length() == 0) {
|
||||
return new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
|
||||
}
|
||||
|
||||
RemoteOperationResult result = null;
|
||||
ArrayList<Object> resultData = new ArrayList<Object>();
|
||||
|
||||
try {
|
||||
// Parse xml response and obtain the list of shares
|
||||
InputStream is = new ByteArrayInputStream(serverResponse.getBytes());
|
||||
if (mShareXmlParser == null) {
|
||||
Log_OC.w(TAG, "No ShareXmlParser provided, creating new instance ");
|
||||
mShareXmlParser = new ShareXMLParser();
|
||||
}
|
||||
List<OCShare> shares = mShareXmlParser.parseXMLResponse(is);
|
||||
|
||||
if (mShareXmlParser.isSuccess()) {
|
||||
if ((shares != null && shares.size() > 0) || !mOneOrMoreSharesRequired) {
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.OK);
|
||||
if (shares != null) {
|
||||
for (OCShare share : shares) {
|
||||
resultData.add(share);
|
||||
// build the share link if not in the response (only received when the share is created)
|
||||
if (share.getShareType() == ShareType.PUBLIC_LINK &&
|
||||
(share.getShareLink() == null ||
|
||||
share.getShareLink().length() <= 0) &&
|
||||
share.getToken().length() > 0
|
||||
) {
|
||||
if (mServerBaseUri != null) {
|
||||
String sharingLinkPath = ShareUtils.getSharingLinkPath(mOwnCloudVersion);
|
||||
share.setShareLink(mServerBaseUri + sharingLinkPath + share.getToken());
|
||||
} else {
|
||||
Log_OC.e(TAG, "Couldn't build link for public share");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setData(resultData);
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
|
||||
Log_OC.e(TAG, "Successful status with no share in the response");
|
||||
}
|
||||
|
||||
} else if (mShareXmlParser.isWrongParameter()){
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER);
|
||||
resultData.add(mShareXmlParser.getMessage());
|
||||
result.setData(resultData);
|
||||
|
||||
} else if (mShareXmlParser.isNotFound()){
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND);
|
||||
resultData.add(mShareXmlParser.getMessage());
|
||||
result.setData(resultData);
|
||||
|
||||
} else if (mShareXmlParser.isForbidden()) {
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN);
|
||||
resultData.add(mShareXmlParser.getMessage());
|
||||
result.setData(resultData);
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
|
||||
|
||||
}
|
||||
|
||||
} catch (XmlPullParserException e) {
|
||||
Log_OC.e(TAG, "Error parsing response from server ", e);
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
|
||||
|
||||
} catch (IOException e) {
|
||||
Log_OC.e(TAG, "Error reading response from server ", e);
|
||||
result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
package com.owncloud.android.lib.resources.shares;
|
||||
|
||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
|
||||
/**
|
||||
* Contains Constants for Share Operation
|
||||
*
|
||||
@@ -36,7 +38,16 @@ public class ShareUtils {
|
||||
// OCS Route
|
||||
public static final String SHARING_API_PATH ="/ocs/v1.php/apps/files_sharing/api/v1/shares";
|
||||
|
||||
// String to build the link with the token of a share: server address + "/public.php?service=files&t=" + token
|
||||
public static final String SHARING_LINK_TOKEN = "/public.php?service=files&t=";
|
||||
|
||||
// String to build the link with the token of a share:
|
||||
public static final String SHARING_LINK_PATH_BEFORE_VERSION_8 = "/public.php?service=files&t=";
|
||||
public static final String SHARING_LINK_PATH_AFTER_VERSION_8 = "/index.php/s/";
|
||||
|
||||
public static String getSharingLinkPath(OwnCloudVersion version){
|
||||
if (version!= null && version.isAfter8Version()){
|
||||
return SHARING_LINK_PATH_AFTER_VERSION_8;
|
||||
} else {
|
||||
return SHARING_LINK_PATH_BEFORE_VERSION_8;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ShareXMLParser {
|
||||
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_MESSAGE = "message";
|
||||
|
||||
private static final String NODE_DATA = "data";
|
||||
private static final String NODE_ELEMENT = "element";
|
||||
@@ -75,18 +75,20 @@ public class ShareXMLParser {
|
||||
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_SHARE_WITH_DISPLAY_NAME = "share_with_displayname";
|
||||
|
||||
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 static final int ERROR_WRONG_PARAMETER = 400;
|
||||
private static final int ERROR_FORBIDDEN = 403;
|
||||
private static final int ERROR_NOT_FOUND = 404;
|
||||
|
||||
private String mStatus;
|
||||
private int mStatusCode;
|
||||
private String mMessage;
|
||||
|
||||
// Getters and Setters
|
||||
public String getStatus() {
|
||||
@@ -104,21 +106,36 @@ public class ShareXMLParser {
|
||||
public void setStatusCode(int statusCode) {
|
||||
this.mStatusCode = statusCode;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return mMessage;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.mMessage = message;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public ShareXMLParser() {
|
||||
mStatusCode = 100;
|
||||
mStatusCode = -1;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return mStatusCode == SUCCESS;
|
||||
}
|
||||
public boolean isFailure() {
|
||||
return mStatusCode == FAILURE;
|
||||
|
||||
public boolean isForbidden() {
|
||||
return mStatusCode == ERROR_FORBIDDEN;
|
||||
}
|
||||
public boolean isFileNotFound() {
|
||||
return mStatusCode == FILE_NOT_FOUND;
|
||||
|
||||
public boolean isNotFound() {
|
||||
return mStatusCode == ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
public boolean isWrongParameter() {
|
||||
return mStatusCode == ERROR_WRONG_PARAMETER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse is as response of Share API
|
||||
* @param is
|
||||
@@ -126,7 +143,8 @@ public class ShareXMLParser {
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException, IOException {
|
||||
public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException,
|
||||
IOException {
|
||||
|
||||
try {
|
||||
// XMLPullParser
|
||||
@@ -151,7 +169,8 @@ public class ShareXMLParser {
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException, 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) {
|
||||
@@ -195,6 +214,9 @@ public class ShareXMLParser {
|
||||
} else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) {
|
||||
setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE)));
|
||||
|
||||
} else if (name.equalsIgnoreCase(NODE_MESSAGE)) {
|
||||
setMessage(readNode(parser, NODE_MESSAGE));
|
||||
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
@@ -209,7 +231,8 @@ public class ShareXMLParser {
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException,
|
||||
IOException {
|
||||
ArrayList<OCShare> shares = new ArrayList<OCShare>();
|
||||
OCShare share = null;
|
||||
|
||||
@@ -259,7 +282,8 @@ public class ShareXMLParser {
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private void readElement(XmlPullParser parser, ArrayList<OCShare> shares) throws XmlPullParserException, IOException {
|
||||
private void readElement(XmlPullParser parser, ArrayList<OCShare> shares)
|
||||
throws XmlPullParserException, IOException {
|
||||
parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT);
|
||||
|
||||
OCShare share = new OCShare();
|
||||
@@ -273,7 +297,8 @@ public class ShareXMLParser {
|
||||
String name = parser.getName();
|
||||
|
||||
if (name.equalsIgnoreCase(NODE_ELEMENT)) {
|
||||
// patch to work around servers responding with extra <element> surrounding all the shares on the same file before
|
||||
// patch to work around servers responding with extra <element> surrounding all
|
||||
// the shares on the same file before
|
||||
// https://github.com/owncloud/core/issues/6992 was fixed
|
||||
readElement(parser, shares);
|
||||
|
||||
@@ -327,6 +352,11 @@ public class ShareXMLParser {
|
||||
} else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) {
|
||||
share.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME));
|
||||
|
||||
} else if (name.equalsIgnoreCase(NODE_URL)) {
|
||||
share.setShareType(ShareType.PUBLIC_LINK);
|
||||
String value = readNode(parser, NODE_URL);
|
||||
share.setShareLink(value);
|
||||
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
@@ -338,13 +368,12 @@ public class ShareXMLParser {
|
||||
}
|
||||
|
||||
private boolean isValidShare(OCShare share) {
|
||||
return ((share.getIdRemoteShared() > -1) &&
|
||||
(share.getShareType() == ShareType.PUBLIC_LINK) // at this moment we only care about public shares
|
||||
);
|
||||
return (share.getRemoteId() > -1);
|
||||
}
|
||||
|
||||
private void fixPathForFolder(OCShare share) {
|
||||
if (share.isFolder() && share.getPath() != null && share.getPath().length() > 0 && !share.getPath().endsWith(FileUtils.PATH_SEPARATOR)) {
|
||||
if (share.isFolder() && share.getPath() != null && share.getPath().length() > 0 &&
|
||||
!share.getPath().endsWith(FileUtils.PATH_SEPARATOR)) {
|
||||
share.setPath(share.getPath() + FileUtils.PATH_SEPARATOR);
|
||||
}
|
||||
}
|
||||
@@ -357,7 +386,8 @@ public class ShareXMLParser {
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, IOException{
|
||||
private String readNode (XmlPullParser parser, String node) throws XmlPullParserException,
|
||||
IOException{
|
||||
parser.require(XmlPullParser.START_TAG, ns, node);
|
||||
String value = readText(parser);
|
||||
//Log_OC.d(TAG, "node= " + node + ", value= " + value);
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author David A. Velasco
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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 android.net.Uri;
|
||||
import android.util.Pair;
|
||||
|
||||
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.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.methods.PutMethod;
|
||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
import org.apache.http.HttpStatus;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Updates parameters of an existing Share resource, known its remote ID.
|
||||
*
|
||||
* Allow updating several parameters, triggering a request to the server per parameter.
|
||||
*/
|
||||
|
||||
public class UpdateRemoteShareOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = GetRemoteShareOperation.class.getSimpleName();
|
||||
|
||||
private static final String PARAM_PASSWORD = "password";
|
||||
private static final String PARAM_EXPIRATION_DATE = "expireDate";
|
||||
private static final String PARAM_PERMISSIONS = "permissions";
|
||||
private static final String FORMAT_EXPIRATION_DATE = "yyyy-MM-dd";
|
||||
private static final String ENTITY_CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||
private static final String ENTITY_CHARSET = "UTF-8";
|
||||
|
||||
|
||||
/** Identifier of the share to update */
|
||||
private long mRemoteId;
|
||||
|
||||
/** Password to set for the public link */
|
||||
private String mPassword;
|
||||
|
||||
/** Expiration date to set for the public link */
|
||||
private long mExpirationDateInMillis;
|
||||
|
||||
/** Access permissions for the file bound to the share */
|
||||
private int mPermissions;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor. No update is initialized by default, need to be applied with setters below.
|
||||
*
|
||||
* @param remoteId Identifier of the share to update.
|
||||
*/
|
||||
public UpdateRemoteShareOperation(long remoteId) {
|
||||
mRemoteId = remoteId;
|
||||
mPassword = null; // no update
|
||||
mExpirationDateInMillis = 0; // no update
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set password to update in Share resource.
|
||||
*
|
||||
* @param password Password to set to the target share.
|
||||
* Empty string clears the current password.
|
||||
* Null results in no update applied to the password.
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
mPassword = password;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set expiration date to update in Share resource.
|
||||
*
|
||||
* @param expirationDateInMillis Expiration date to set to the target share.
|
||||
* A negative value clears the current expiration date.
|
||||
* Zero value (start-of-epoch) results in no update done on
|
||||
* the expiration date.
|
||||
*/
|
||||
public void setExpirationDate(long expirationDateInMillis) {
|
||||
mExpirationDateInMillis = expirationDateInMillis;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set permissions to update in Share resource.
|
||||
*
|
||||
* @param permissions Permissions date to set to the target share.
|
||||
* Values <= 0 result in no update applied to the permissions.
|
||||
*/
|
||||
public void setPermissions(int permissions) {
|
||||
mPermissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
int status = -1;
|
||||
|
||||
/// prepare array of parameters to update
|
||||
List<Pair<String, String>> parametersToUpdate = new ArrayList<Pair<String, String>>();
|
||||
if (mPassword != null) {
|
||||
parametersToUpdate.add(new Pair<String, String>(PARAM_PASSWORD, mPassword));
|
||||
}
|
||||
if (mExpirationDateInMillis < 0) {
|
||||
// clear expiration date
|
||||
parametersToUpdate.add(new Pair(PARAM_EXPIRATION_DATE, ""));
|
||||
|
||||
} else if (mExpirationDateInMillis > 0) {
|
||||
// set expiration date
|
||||
DateFormat dateFormat = new SimpleDateFormat(FORMAT_EXPIRATION_DATE);
|
||||
Calendar expirationDate = Calendar.getInstance();
|
||||
expirationDate.setTimeInMillis(mExpirationDateInMillis);
|
||||
String formattedExpirationDate = dateFormat.format(expirationDate.getTime());
|
||||
parametersToUpdate.add(new Pair(PARAM_EXPIRATION_DATE, formattedExpirationDate));
|
||||
|
||||
} // else, ignore - no update
|
||||
if (mPermissions > 0) {
|
||||
// set permissions
|
||||
parametersToUpdate.add(new Pair(PARAM_PERMISSIONS, Integer.toString(mPermissions)));
|
||||
}
|
||||
|
||||
/* TODO complete rest of parameters
|
||||
if (mPublicUpload != null) {
|
||||
parametersToUpdate.add(new Pair("publicUpload", mPublicUpload.toString());
|
||||
}
|
||||
*/
|
||||
|
||||
/// perform required PUT requests
|
||||
PutMethod put = null;
|
||||
String uriString = null;
|
||||
|
||||
try{
|
||||
Uri requestUri = client.getBaseUri();
|
||||
Uri.Builder uriBuilder = requestUri.buildUpon();
|
||||
uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH.substring(1));
|
||||
uriBuilder.appendEncodedPath(Long.toString(mRemoteId));
|
||||
uriString = uriBuilder.build().toString();
|
||||
|
||||
for (Pair<String, String> parameter : parametersToUpdate) {
|
||||
if (put != null) {
|
||||
put.releaseConnection();
|
||||
}
|
||||
put = new PutMethod(uriString);
|
||||
put.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
put.setRequestEntity(new StringRequestEntity(
|
||||
parameter.first + "=" + parameter.second,
|
||||
ENTITY_CONTENT_TYPE,
|
||||
ENTITY_CHARSET
|
||||
));
|
||||
|
||||
status = client.executeMethod(put);
|
||||
|
||||
if (status == HttpStatus.SC_OK) {
|
||||
String response = put.getResponseBodyAsString();
|
||||
|
||||
// Parse xml response
|
||||
ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
|
||||
new ShareXMLParser()
|
||||
);
|
||||
parser.setOwnCloudVersion(client.getOwnCloudVersion());
|
||||
parser.setServerBaseUri(client.getBaseUri());
|
||||
result = parser.parse(response);
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, put.getResponseHeaders());
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log_OC.e(TAG, "Exception while updating remote share ", e);
|
||||
if (put != null) {
|
||||
put.releaseConnection();
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (put != null) {
|
||||
put.releaseConnection();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
* @author masensio
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Enum for Boolean Type in OCCapability parameters, with values:
|
||||
* -1 - Unknown
|
||||
* 0 - False
|
||||
* 1 - True
|
||||
*/
|
||||
public enum CapabilityBooleanType {
|
||||
UNKNOWN (-1),
|
||||
FALSE (0),
|
||||
TRUE (1);
|
||||
|
||||
private int value;
|
||||
|
||||
CapabilityBooleanType(int value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static CapabilityBooleanType fromValue(int value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case -1:
|
||||
return UNKNOWN;
|
||||
case 0:
|
||||
return FALSE;
|
||||
case 1:
|
||||
return TRUE;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static CapabilityBooleanType fromBooleanValue(boolean boolValue){
|
||||
if (boolValue){
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUnknown(){
|
||||
return getValue() == -1;
|
||||
}
|
||||
|
||||
public boolean isFalse(){
|
||||
return getValue() == 0;
|
||||
}
|
||||
|
||||
public boolean isTrue(){
|
||||
return getValue() == 1;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,281 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author masensio
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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 android.net.Uri;
|
||||
|
||||
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.utils.Log_OC;
|
||||
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Get the Capabilities from the server
|
||||
*
|
||||
* Save in Result.getData in a OCCapability object
|
||||
*/
|
||||
public class GetRemoteCapabilitiesOperation extends RemoteOperation {
|
||||
|
||||
private static final String TAG = GetRemoteCapabilitiesOperation.class.getSimpleName();
|
||||
|
||||
|
||||
// OCS Routes
|
||||
private static final String OCS_ROUTE = "ocs/v1.php/cloud/capabilities";
|
||||
|
||||
// Arguments - names
|
||||
private static final String PARAM_FORMAT = "format";
|
||||
|
||||
// Arguments - constant values
|
||||
private static final String VALUE_FORMAT = "json";
|
||||
|
||||
// JSON Node names
|
||||
private static final String NODE_OCS = "ocs";
|
||||
|
||||
private static final String NODE_META = "meta";
|
||||
|
||||
private static final String NODE_DATA = "data";
|
||||
private static final String NODE_VERSION = "version";
|
||||
|
||||
private static final String NODE_CAPABILITIES = "capabilities";
|
||||
private static final String NODE_CORE = "core";
|
||||
|
||||
private static final String NODE_FILES_SHARING = "files_sharing";
|
||||
private static final String NODE_PUBLIC = "public";
|
||||
private static final String NODE_PASSWORD = "password";
|
||||
private static final String NODE_EXPIRE_DATE = "expire_date";
|
||||
private static final String NODE_USER = "user";
|
||||
private static final String NODE_FEDERATION = "federation";
|
||||
private static final String NODE_FILES = "files";
|
||||
|
||||
private static final String PROPERTY_STATUS = "status";
|
||||
private static final String PROPERTY_STATUSCODE = "statuscode";
|
||||
private static final String PROPERTY_MESSAGE = "message";
|
||||
|
||||
private static final String PROPERTY_POLLINTERVAL = "pollinterval";
|
||||
|
||||
private static final String PROPERTY_MAJOR = "major";
|
||||
private static final String PROPERTY_MINOR = "minor";
|
||||
private static final String PROPERTY_MICRO = "micro";
|
||||
private static final String PROPERTY_STRING = "string";
|
||||
private static final String PROPERTY_EDITION = "edition";
|
||||
|
||||
private static final String PROPERTY_API_ENABLED = "api_enabled";
|
||||
private static final String PROPERTY_ENABLED = "enabled";
|
||||
private static final String PROPERTY_ENFORCED = "enforced";
|
||||
private static final String PROPERTY_DAYS = "days";
|
||||
private static final String PROPERTY_SEND_MAIL = "send_mail";
|
||||
private static final String PROPERTY_UPLOAD = "upload";
|
||||
private static final String PROPERTY_RESHARING = "resharing";
|
||||
private static final String PROPERTY_OUTGOING = "outgoing";
|
||||
private static final String PROPERTY_INCOMING = "incoming";
|
||||
|
||||
private static final String PROPERTY_BIGFILECHUNKING = "bigfilechunking";
|
||||
private static final String PROPERTY_UNDELETE = "undelete";
|
||||
private static final String PROPERTY_VERSIONING = "versioning";
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
public GetRemoteCapabilitiesOperation() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
int status;
|
||||
GetMethod get = null;
|
||||
|
||||
try {
|
||||
Uri requestUri = client.getBaseUri();
|
||||
Uri.Builder uriBuilder = requestUri.buildUpon();
|
||||
uriBuilder.appendEncodedPath(OCS_ROUTE); // avoid starting "/" in this method
|
||||
uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT);
|
||||
|
||||
// Get Method
|
||||
get = new GetMethod(uriBuilder.build().toString());
|
||||
get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
|
||||
|
||||
status = client.executeMethod(get);
|
||||
|
||||
if(isSuccess(status)) {
|
||||
String response = get.getResponseBodyAsString();
|
||||
Log_OC.d(TAG, "Successful response: " + response);
|
||||
|
||||
// Parse the response
|
||||
JSONObject respJSON = new JSONObject(response);
|
||||
JSONObject respOCS = respJSON.getJSONObject(NODE_OCS);
|
||||
JSONObject respMeta = respOCS.getJSONObject(NODE_META);
|
||||
JSONObject respData = respOCS.getJSONObject(NODE_DATA);
|
||||
|
||||
// Read meta
|
||||
boolean statusProp = respMeta.getString(PROPERTY_STATUS).equalsIgnoreCase("ok");
|
||||
int statuscode = respMeta.getInt(PROPERTY_STATUSCODE);
|
||||
String message = respMeta.getString(PROPERTY_MESSAGE);
|
||||
|
||||
if (statusProp) {
|
||||
ArrayList<Object> data = new ArrayList<Object>(); // For result data
|
||||
OCCapability capability = new OCCapability();
|
||||
// Add Version
|
||||
if (respData.has(NODE_VERSION)) {
|
||||
JSONObject respVersion = respData.getJSONObject(NODE_VERSION);
|
||||
capability.setVersionMayor(respVersion.getInt(PROPERTY_MAJOR));
|
||||
capability.setVersionMinor(respVersion.getInt(PROPERTY_MINOR));
|
||||
capability.setVersionMicro(respVersion.getInt(PROPERTY_MICRO));
|
||||
capability.setVersionString(respVersion.getString(PROPERTY_STRING));
|
||||
capability.setVersionEdition(respVersion.getString(PROPERTY_EDITION));
|
||||
Log_OC.d(TAG, "*** Added " + NODE_VERSION);
|
||||
}
|
||||
|
||||
// Capabilities Object
|
||||
if (respData.has(NODE_CAPABILITIES)) {
|
||||
JSONObject respCapabilities = respData.getJSONObject(NODE_CAPABILITIES);
|
||||
|
||||
// Add Core: pollinterval
|
||||
if (respCapabilities.has(NODE_CORE)) {
|
||||
JSONObject respCore = respCapabilities.getJSONObject(NODE_CORE);
|
||||
capability.setCorePollinterval(respCore.getInt(PROPERTY_POLLINTERVAL));
|
||||
Log_OC.d(TAG, "*** Added " + NODE_CORE);
|
||||
}
|
||||
|
||||
// Add files_sharing: public, user, resharing
|
||||
if (respCapabilities.has(NODE_FILES_SHARING)) {
|
||||
JSONObject respFilesSharing = respCapabilities.getJSONObject(NODE_FILES_SHARING);
|
||||
if (respFilesSharing.has(PROPERTY_API_ENABLED)) {
|
||||
capability.setFilesSharingApiEnabled(CapabilityBooleanType.fromBooleanValue(
|
||||
respFilesSharing.getBoolean(PROPERTY_API_ENABLED)));
|
||||
}
|
||||
|
||||
if (respFilesSharing.has(NODE_PUBLIC)) {
|
||||
JSONObject respPublic = respFilesSharing.getJSONObject(NODE_PUBLIC);
|
||||
capability.setFilesSharingPublicEnabled(CapabilityBooleanType.fromBooleanValue(
|
||||
respPublic.getBoolean(PROPERTY_ENABLED)));
|
||||
if(respPublic.has(NODE_PASSWORD)) {
|
||||
capability.setFilesSharingPublicPasswordEnforced(
|
||||
CapabilityBooleanType.fromBooleanValue(
|
||||
respPublic.getJSONObject(NODE_PASSWORD).getBoolean(PROPERTY_ENFORCED)));
|
||||
}
|
||||
if(respPublic.has(NODE_EXPIRE_DATE)){
|
||||
JSONObject respExpireDate = respPublic.getJSONObject(NODE_EXPIRE_DATE);
|
||||
capability.setFilesSharingPublicExpireDateEnabled(
|
||||
CapabilityBooleanType.fromBooleanValue(
|
||||
respExpireDate.getBoolean(PROPERTY_ENABLED)));
|
||||
if (respExpireDate.has(PROPERTY_DAYS)) {
|
||||
capability.setFilesSharingPublicExpireDateDays(
|
||||
respExpireDate.getInt(PROPERTY_DAYS));
|
||||
}
|
||||
if (respExpireDate.has(PROPERTY_ENFORCED)) {
|
||||
capability.setFilesSharingPublicExpireDateEnforced(
|
||||
CapabilityBooleanType.fromBooleanValue(
|
||||
respExpireDate.getBoolean(PROPERTY_ENFORCED)));
|
||||
}
|
||||
}
|
||||
if (respPublic.has(PROPERTY_UPLOAD)){
|
||||
capability.setFilesSharingPublicUpload(CapabilityBooleanType.fromBooleanValue(
|
||||
respPublic.getBoolean(PROPERTY_UPLOAD)));
|
||||
}
|
||||
}
|
||||
|
||||
if (respFilesSharing.has(NODE_USER)) {
|
||||
JSONObject respUser = respFilesSharing.getJSONObject(NODE_USER);
|
||||
capability.setFilesSharingUserSendMail(CapabilityBooleanType.fromBooleanValue(
|
||||
respUser.getBoolean(PROPERTY_SEND_MAIL)));
|
||||
}
|
||||
|
||||
capability.setFilesSharingResharing(CapabilityBooleanType.fromBooleanValue(
|
||||
respFilesSharing.getBoolean(PROPERTY_RESHARING)));
|
||||
if (respFilesSharing.has(NODE_FEDERATION)) {
|
||||
JSONObject respFederation = respFilesSharing.getJSONObject(NODE_FEDERATION);
|
||||
capability.setFilesSharingFederationOutgoing(
|
||||
CapabilityBooleanType.fromBooleanValue(respFederation.getBoolean(PROPERTY_OUTGOING)));
|
||||
capability.setFilesSharingFederationIncoming(CapabilityBooleanType.fromBooleanValue(
|
||||
respFederation.getBoolean(PROPERTY_INCOMING)));
|
||||
}
|
||||
Log_OC.d(TAG, "*** Added " + NODE_FILES_SHARING);
|
||||
}
|
||||
|
||||
|
||||
if (respCapabilities.has(NODE_FILES)) {
|
||||
JSONObject respFiles = respCapabilities.getJSONObject(NODE_FILES);
|
||||
// Add files
|
||||
capability.setFilesBigFileChuncking(CapabilityBooleanType.fromBooleanValue(
|
||||
respFiles.getBoolean(PROPERTY_BIGFILECHUNKING)));
|
||||
if (respFiles.has(PROPERTY_UNDELETE)) {
|
||||
capability.setFilesUndelete(CapabilityBooleanType.fromBooleanValue(
|
||||
respFiles.getBoolean(PROPERTY_UNDELETE)));
|
||||
}
|
||||
capability.setFilesVersioning(CapabilityBooleanType.fromBooleanValue(
|
||||
respFiles.getBoolean(PROPERTY_VERSIONING)));
|
||||
Log_OC.d(TAG, "*** Added " + NODE_FILES);
|
||||
}
|
||||
}
|
||||
// Result
|
||||
data.add(capability);
|
||||
result = new RemoteOperationResult(true, status, get.getResponseHeaders());
|
||||
result.setData(data);
|
||||
|
||||
Log_OC.d(TAG, "*** Get Capabilities completed ");
|
||||
} else {
|
||||
result = new RemoteOperationResult(statusProp, statuscode, null);
|
||||
Log_OC.e(TAG, "Failed response while getting capabilities from the server ");
|
||||
Log_OC.e(TAG, "*** status: " + statusProp + "; message: " + message);
|
||||
}
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(false, status, get.getResponseHeaders());
|
||||
String response = get.getResponseBodyAsString();
|
||||
Log_OC.e(TAG, "Failed response while getting capabilities from the server ");
|
||||
if (response != null) {
|
||||
Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response);
|
||||
} else {
|
||||
Log_OC.e(TAG, "*** status code: " + status);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
Log_OC.e(TAG, "Exception while getting capabilities", e);
|
||||
|
||||
} finally {
|
||||
if (get != null) {
|
||||
get.releaseConnection();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isSuccess(int status) {
|
||||
return (status == HttpStatus.SC_OK);
|
||||
}
|
||||
}
|
||||
@@ -103,9 +103,7 @@ public class GetRemoteStatusOperation extends RemoteOperation {
|
||||
);
|
||||
get.releaseConnection();
|
||||
get = new GetMethod(redirectedLocation);
|
||||
status = client.executeMethod(
|
||||
get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT
|
||||
);
|
||||
status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
|
||||
mLatestResult = new RemoteOperationResult(
|
||||
(status == HttpStatus.SC_OK),
|
||||
status,
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
/* ownCloud Android Library is available under MIT license
|
||||
* @author masensio
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Contains data of the Capabilities for an account, from the Capabilities API
|
||||
*/
|
||||
public class OCCapability {
|
||||
|
||||
private static final String TAG = OCCapability.class.getSimpleName();
|
||||
|
||||
private long mId;
|
||||
private String mAccountName;
|
||||
|
||||
// Server version
|
||||
private int mVersionMayor;
|
||||
private int mVersionMinor;
|
||||
private int mVersionMicro;
|
||||
private String mVersionString;
|
||||
private String mVersionEdition;
|
||||
|
||||
// Core PollInterval
|
||||
private int mCorePollinterval;
|
||||
|
||||
// Files Sharing
|
||||
private CapabilityBooleanType mFilesSharingApiEnabled;
|
||||
|
||||
private CapabilityBooleanType mFilesSharingPublicEnabled;
|
||||
private CapabilityBooleanType mFilesSharingPublicPasswordEnforced;
|
||||
private CapabilityBooleanType mFilesSharingPublicExpireDateEnabled;
|
||||
private int mFilesSharingPublicExpireDateDays;
|
||||
private CapabilityBooleanType mFilesSharingPublicExpireDateEnforced;
|
||||
private CapabilityBooleanType mFilesSharingPublicSendMail;
|
||||
private CapabilityBooleanType mFilesSharingPublicUpload;
|
||||
|
||||
private CapabilityBooleanType mFilesSharingUserSendMail;
|
||||
|
||||
private CapabilityBooleanType mFilesSharingResharing;
|
||||
|
||||
private CapabilityBooleanType mFilesSharingFederationOutgoing;
|
||||
private CapabilityBooleanType mFilesSharingFederationIncoming;
|
||||
|
||||
// Files
|
||||
private CapabilityBooleanType mFilesBigFileChuncking;
|
||||
private CapabilityBooleanType mFilesUndelete;
|
||||
private CapabilityBooleanType mFilesVersioning;
|
||||
|
||||
public OCCapability(){
|
||||
mId = 0;
|
||||
mAccountName = "";
|
||||
|
||||
mVersionMayor = 0;
|
||||
mVersionMinor = 0;
|
||||
mVersionMicro = 0;
|
||||
mVersionString = "";
|
||||
mVersionString = "";
|
||||
|
||||
mCorePollinterval = 0;
|
||||
|
||||
mFilesSharingApiEnabled = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingPublicEnabled = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingPublicPasswordEnforced = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingPublicExpireDateEnabled = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingPublicExpireDateDays = 0;
|
||||
mFilesSharingPublicExpireDateEnforced = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingPublicSendMail = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingPublicUpload = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingUserSendMail = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingResharing = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingFederationOutgoing = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesSharingFederationIncoming = CapabilityBooleanType.UNKNOWN;
|
||||
|
||||
mFilesBigFileChuncking = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesUndelete = CapabilityBooleanType.UNKNOWN;
|
||||
mFilesVersioning = CapabilityBooleanType.UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
// Getters and Setters
|
||||
public String getAccountName() {
|
||||
return mAccountName;
|
||||
}
|
||||
|
||||
public void setAccountName(String accountName) {
|
||||
this.mAccountName = accountName;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.mId = id;
|
||||
}
|
||||
|
||||
public int getVersionMayor() {
|
||||
return mVersionMayor;
|
||||
}
|
||||
|
||||
public void setVersionMayor(int versionMayor) {
|
||||
this.mVersionMayor = versionMayor;
|
||||
}
|
||||
|
||||
public int getVersionMinor() {
|
||||
return mVersionMinor;
|
||||
}
|
||||
|
||||
public void setVersionMinor(int versionMinor) {
|
||||
this.mVersionMinor = versionMinor;
|
||||
}
|
||||
|
||||
public int getVersionMicro() {
|
||||
return mVersionMicro;
|
||||
}
|
||||
|
||||
public void setVersionMicro(int versionMicro) {
|
||||
this.mVersionMicro = versionMicro;
|
||||
}
|
||||
|
||||
public String getVersionString() {
|
||||
return mVersionString;
|
||||
}
|
||||
|
||||
public void setVersionString(String versionString) {
|
||||
this.mVersionString = versionString;
|
||||
}
|
||||
|
||||
public String getVersionEdition() {
|
||||
return mVersionEdition;
|
||||
}
|
||||
|
||||
public void setVersionEdition(String versionEdition) {
|
||||
this.mVersionEdition = versionEdition;
|
||||
}
|
||||
|
||||
|
||||
public int getCorePollinterval() {
|
||||
return mCorePollinterval;
|
||||
}
|
||||
|
||||
public void setCorePollinterval(int corePollinterval) {
|
||||
this.mCorePollinterval = corePollinterval;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingApiEnabled() {
|
||||
return mFilesSharingApiEnabled;
|
||||
}
|
||||
|
||||
public void setFilesSharingApiEnabled(CapabilityBooleanType filesSharingApiEnabled) {
|
||||
this.mFilesSharingApiEnabled = filesSharingApiEnabled;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingPublicEnabled() {
|
||||
return mFilesSharingPublicEnabled;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicEnabled(CapabilityBooleanType filesSharingPublicEnabled) {
|
||||
this.mFilesSharingPublicEnabled = filesSharingPublicEnabled;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingPublicPasswordEnforced() {
|
||||
return mFilesSharingPublicPasswordEnforced;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicPasswordEnforced(CapabilityBooleanType filesSharingPublicPasswordEnforced) {
|
||||
this.mFilesSharingPublicPasswordEnforced = filesSharingPublicPasswordEnforced;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingPublicExpireDateEnabled() {
|
||||
return mFilesSharingPublicExpireDateEnabled;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicExpireDateEnabled(CapabilityBooleanType filesSharingPublicExpireDateEnabled) {
|
||||
this.mFilesSharingPublicExpireDateEnabled = filesSharingPublicExpireDateEnabled;
|
||||
}
|
||||
|
||||
public int getFilesSharingPublicExpireDateDays() {
|
||||
return mFilesSharingPublicExpireDateDays;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicExpireDateDays(int filesSharingPublicExpireDateDays) {
|
||||
this.mFilesSharingPublicExpireDateDays = filesSharingPublicExpireDateDays;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingPublicExpireDateEnforced() {
|
||||
return mFilesSharingPublicExpireDateEnforced;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicExpireDateEnforced(CapabilityBooleanType filesSharingPublicExpireDateEnforced) {
|
||||
this.mFilesSharingPublicExpireDateEnforced = filesSharingPublicExpireDateEnforced;
|
||||
}
|
||||
|
||||
|
||||
public CapabilityBooleanType getFilesSharingPublicSendMail() {
|
||||
return mFilesSharingPublicSendMail;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicSendMail(CapabilityBooleanType filesSharingPublicSendMail) {
|
||||
this.mFilesSharingPublicSendMail = filesSharingPublicSendMail;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingPublicUpload() {
|
||||
return mFilesSharingPublicUpload;
|
||||
}
|
||||
|
||||
public void setFilesSharingPublicUpload(CapabilityBooleanType filesSharingPublicUpload) {
|
||||
this.mFilesSharingPublicUpload = filesSharingPublicUpload;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingUserSendMail() {
|
||||
return mFilesSharingUserSendMail;
|
||||
}
|
||||
|
||||
public void setFilesSharingUserSendMail(CapabilityBooleanType filesSharingUserSendMail) {
|
||||
this.mFilesSharingUserSendMail = filesSharingUserSendMail;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingResharing() {
|
||||
return mFilesSharingResharing;
|
||||
}
|
||||
|
||||
public void setFilesSharingResharing(CapabilityBooleanType filesSharingResharing) {
|
||||
this.mFilesSharingResharing = filesSharingResharing;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingFederationOutgoing() {
|
||||
return mFilesSharingFederationOutgoing;
|
||||
}
|
||||
|
||||
public void setFilesSharingFederationOutgoing(CapabilityBooleanType filesSharingFederationOutgoing) {
|
||||
this.mFilesSharingFederationOutgoing = filesSharingFederationOutgoing;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesSharingFederationIncoming() {
|
||||
return mFilesSharingFederationIncoming;
|
||||
}
|
||||
|
||||
public void setFilesSharingFederationIncoming(CapabilityBooleanType filesSharingFederationIncoming) {
|
||||
this.mFilesSharingFederationIncoming = filesSharingFederationIncoming;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesBigFileChuncking() {
|
||||
return mFilesBigFileChuncking;
|
||||
}
|
||||
|
||||
public void setFilesBigFileChuncking(CapabilityBooleanType filesBigFileChuncking) {
|
||||
this.mFilesBigFileChuncking = filesBigFileChuncking;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesUndelete() {
|
||||
return mFilesUndelete;
|
||||
}
|
||||
|
||||
public void setFilesUndelete(CapabilityBooleanType filesUndelete) {
|
||||
this.mFilesUndelete = filesUndelete;
|
||||
}
|
||||
|
||||
public CapabilityBooleanType getFilesVersioning() {
|
||||
return mFilesVersioning;
|
||||
}
|
||||
|
||||
public void setFilesVersioning(CapabilityBooleanType filesVersioning) {
|
||||
this.mFilesVersioning = filesVersioning;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -38,6 +38,16 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
|
||||
0x04050000);
|
||||
|
||||
public static final int MINIMUM_VERSION_FOR_SHARING_API = 0x05001B00; // 5.0.27
|
||||
|
||||
public static final int MINIMUM_VERSION_WITH_FORBIDDEN_CHARS = 0x08010000; // 8.1
|
||||
|
||||
public static final int MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS = 0x07080000; // 7.8.0
|
||||
|
||||
public static final int MINIMUM_VERSION_FOR_SEARCHING_USERS = 0x08020000; //8.2
|
||||
|
||||
public static final int VERSION_8 = 0x08000000; // 8.0
|
||||
|
||||
public static final int MINIMUM_VERSION_CAPABILITIES_API = 0x08010000; // 8.1
|
||||
|
||||
private static final int MAX_DOTS = 3;
|
||||
|
||||
@@ -120,6 +130,26 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
|
||||
public boolean isSharedSupported() {
|
||||
return (mVersion >= MINIMUM_VERSION_FOR_SHARING_API);
|
||||
}
|
||||
|
||||
public boolean isVersionWithForbiddenCharacters() {
|
||||
return (mVersion >= MINIMUM_VERSION_WITH_FORBIDDEN_CHARS);
|
||||
}
|
||||
|
||||
public boolean supportsRemoteThumbnails() {
|
||||
return (mVersion >= MINIMUM_SERVER_VERSION_FOR_REMOTE_THUMBNAILS);
|
||||
}
|
||||
|
||||
public boolean isAfter8Version(){
|
||||
return (mVersion >= VERSION_8);
|
||||
}
|
||||
|
||||
public boolean isSearchUsersSupported() {
|
||||
return (mVersion >= MINIMUM_VERSION_FOR_SEARCHING_USERS);
|
||||
}
|
||||
|
||||
public boolean isVersionWithCapabilitiesAPI(){
|
||||
return (mVersion>= MINIMUM_VERSION_CAPABILITIES_API);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class GetRemoteUserNameOperation extends RemoteOperation {
|
||||
private static final String TAG = GetRemoteUserNameOperation.class.getSimpleName();
|
||||
|
||||
// OCS Route
|
||||
private static final String OCS_ROUTE ="/index.php/ocs/cloud/user?format=json";
|
||||
private static final String OCS_ROUTE ="/index.php/ocs/cloud/user?format=json";
|
||||
|
||||
// JSON Node names
|
||||
private static final String NODE_OCS = "ocs";
|
||||
|
||||
Reference in New Issue
Block a user