mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-10-31 02:17:41 +00:00 
			
		
		
		
	apply codestyle everywhere
This commit is contained in:
		
							parent
							
								
									6d05856fb7
								
							
						
					
					
						commit
						40690df5fa
					
				| @ -22,11 +22,11 @@ | ||||
|    THE SOFTWARE. | ||||
| 
 | ||||
|  --> | ||||
|   | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     package="com.owncloud.android.lib" | ||||
| 
 | ||||
| <manifest package="com.owncloud.android.lib" | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:versionCode="1" | ||||
|     android:versionName="1.0" > | ||||
|     android:versionName="1.0"> | ||||
| 
 | ||||
|     <!-- USE_CREDENTIALS, MANAGE_ACCOUNTS and AUTHENTICATE_ACCOUNTS are needed for API < 23. | ||||
|         In API >= 23 the do not exist anymore --> | ||||
|  | ||||
| @ -11,7 +11,7 @@ import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Dynamic implementation of {@link OwnCloudClientManager}. | ||||
|  * | ||||
|  * <p> | ||||
|  * Wraps instances of {@link SingleSessionManager} and {@link SimpleFactoryManager} and delegates on one | ||||
|  * or the other depending on the known version of the server corresponding to the {@link OwnCloudAccount} | ||||
|  * | ||||
| @ -26,17 +26,17 @@ public class DynamicSessionManager implements OwnCloudClientManager { | ||||
| 
 | ||||
|     @Override | ||||
|     public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) | ||||
|         throws AccountUtils.AccountNotFoundException, | ||||
|                 OperationCanceledException, AuthenticatorException, IOException { | ||||
|             throws AccountUtils.AccountNotFoundException, | ||||
|             OperationCanceledException, AuthenticatorException, IOException { | ||||
| 
 | ||||
|         OwnCloudVersion ownCloudVersion = null; | ||||
|         if (account.getSavedAccount() != null) { | ||||
|             ownCloudVersion = AccountUtils.getServerVersionForAccount( | ||||
|                 account.getSavedAccount(), context | ||||
|                     account.getSavedAccount(), context | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         if (ownCloudVersion !=  null && ownCloudVersion.isSessionMonitoringSupported()) { | ||||
|         if (ownCloudVersion != null && ownCloudVersion.isSessionMonitoringSupported()) { | ||||
|             return mSingleSessionManager.getClientFor(account, context); | ||||
|         } else { | ||||
|             return mSimpleFactoryManager.getClientFor(account, context); | ||||
|  | ||||
| @ -24,14 +24,6 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| 
 | ||||
| import android.accounts.Account; | ||||
| import android.accounts.AccountManager; | ||||
| import android.accounts.AuthenticatorException; | ||||
| @ -39,27 +31,33 @@ import android.accounts.OperationCanceledException; | ||||
| import android.content.Context; | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * OwnCloud Account | ||||
|  *  | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  */ | ||||
| public class OwnCloudAccount { | ||||
| 
 | ||||
|     private Uri mBaseUri;  | ||||
|      | ||||
|     private Uri mBaseUri; | ||||
| 
 | ||||
|     private OwnCloudCredentials mCredentials; | ||||
| 
 | ||||
|     private String mDisplayName; | ||||
|      | ||||
| 
 | ||||
|     private String mSavedAccountName; | ||||
| 
 | ||||
|     private Account mSavedAccount; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor for already saved OC accounts. | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not use for anonymous credentials. | ||||
|      */ | ||||
|     public OwnCloudAccount(Account savedAccount, Context context) throws AccountNotFoundException { | ||||
| @ -77,19 +75,18 @@ public class OwnCloudAccount { | ||||
| 
 | ||||
|         AccountManager ama = AccountManager.get(context.getApplicationContext()); | ||||
|         String baseUrl = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_OC_BASE_URL); | ||||
|         if (baseUrl == null ) { | ||||
|         if (baseUrl == null) { | ||||
|             throw new AccountNotFoundException(mSavedAccount, "Account not found", null); | ||||
|         } | ||||
|         mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, mSavedAccount)); | ||||
|         mDisplayName = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_DISPLAY_NAME); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor for non yet saved OC accounts. | ||||
|      * | ||||
|      * @param baseUri           URI to the OC server to get access to. | ||||
|      * @param credentials       Credentials to authenticate in the server. NULL is valid for anonymous credentials. | ||||
|      * @param baseUri     URI to the OC server to get access to. | ||||
|      * @param credentials Credentials to authenticate in the server. NULL is valid for anonymous credentials. | ||||
|      */ | ||||
|     public OwnCloudAccount(Uri baseUri, OwnCloudCredentials credentials) { | ||||
|         if (baseUri == null) { | ||||
| @ -99,14 +96,13 @@ public class OwnCloudAccount { | ||||
|         mSavedAccountName = null; | ||||
|         mBaseUri = baseUri; | ||||
|         mCredentials = credentials != null ? | ||||
|             credentials : OwnCloudCredentialsFactory.getAnonymousCredentials(); | ||||
|                 credentials : OwnCloudCredentialsFactory.getAnonymousCredentials(); | ||||
|         String username = mCredentials.getUsername(); | ||||
|         if (username != null) { | ||||
|             mSavedAccountName = AccountUtils.buildAccountName(mBaseUri, username); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Method for deferred load of account attributes from AccountManager | ||||
|      * | ||||
| @ -131,13 +127,13 @@ public class OwnCloudAccount { | ||||
|     public Uri getBaseUri() { | ||||
|         return mBaseUri; | ||||
|     } | ||||
|              | ||||
| 
 | ||||
|     public OwnCloudCredentials getCredentials() { | ||||
|         return mCredentials; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public String getName() { | ||||
|     	return mSavedAccountName; | ||||
|         return mSavedAccountName; | ||||
|     } | ||||
| 
 | ||||
|     public Account getSavedAccount() { | ||||
|  | ||||
| @ -29,6 +29,7 @@ import android.accounts.AccountManager; | ||||
| import android.accounts.AccountsException; | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory; | ||||
| @ -40,16 +41,14 @@ import com.owncloud.android.lib.common.network.RedirectionPath; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.common.utils.RandomUtils; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID; | ||||
| 
 | ||||
| public class OwnCloudClient extends HttpClient { | ||||
| @ -94,15 +93,6 @@ public class OwnCloudClient extends HttpClient { | ||||
|         clearCookies(); | ||||
|     } | ||||
| 
 | ||||
|     public void setCredentials(OwnCloudCredentials credentials) { | ||||
|         if (credentials != null) { | ||||
|             mCredentials = credentials; | ||||
|             mCredentials.applyTo(this); | ||||
|         } else { | ||||
|             clearCredentials(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void clearCredentials() { | ||||
|         if (!(mCredentials instanceof OwnCloudAnonymousCredentials)) { | ||||
|             mCredentials = OwnCloudCredentialsFactory.getAnonymousCredentials(); | ||||
| @ -114,7 +104,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|         mCredentials.applyTo(this); | ||||
|     } | ||||
| 
 | ||||
|     public int executeHttpMethod (HttpBaseMethod method) throws Exception { | ||||
|     public int executeHttpMethod(HttpBaseMethod method) throws Exception { | ||||
|         boolean repeatWithFreshCredentials; | ||||
|         int repeatCounter = 0; | ||||
|         int status; | ||||
| @ -125,7 +115,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|             status = method.execute(); | ||||
|             checkFirstRedirection(method); | ||||
| 
 | ||||
|             if(mFollowRedirects && !isIdPRedirection()) { | ||||
|             if (mFollowRedirects && !isIdPRedirection()) { | ||||
|                 status = followRedirection(method).getLastStatus(); | ||||
|             } | ||||
| 
 | ||||
| @ -140,12 +130,12 @@ public class OwnCloudClient extends HttpClient { | ||||
| 
 | ||||
|     private void checkFirstRedirection(HttpBaseMethod method) { | ||||
|         final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER); | ||||
|         if(location != null && !location.isEmpty()) { | ||||
|         if (location != null && !location.isEmpty()) { | ||||
|             mRedirectedLocation = location; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private int executeRedirectedHttpMethod (HttpBaseMethod method) throws Exception { | ||||
|     private int executeRedirectedHttpMethod(HttpBaseMethod method) throws Exception { | ||||
|         boolean repeatWithFreshCredentials; | ||||
|         int repeatCounter = 0; | ||||
|         int status; | ||||
| @ -217,9 +207,9 @@ public class OwnCloudClient extends HttpClient { | ||||
|                 try { | ||||
|                     status = executeRedirectedHttpMethod(method); | ||||
|                 } catch (HttpException e) { | ||||
|                     if(e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) { | ||||
|                     if (e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) { | ||||
|                         status = HttpConstants.HTTP_MOVED_TEMPORARILY; | ||||
|                     } else  { | ||||
|                     } else { | ||||
|                         throw e; | ||||
|                     } | ||||
|                 } | ||||
| @ -242,7 +232,9 @@ public class OwnCloudClient extends HttpClient { | ||||
|     public void exhaustResponse(InputStream responseBodyAsStream) { | ||||
|         if (responseBodyAsStream != null) { | ||||
|             try { | ||||
|                 while (responseBodyAsStream.read(sExhaustBuffer) >= 0) ; | ||||
|                 while (responseBodyAsStream.read(sExhaustBuffer) >= 0) { | ||||
|                     ; | ||||
|                 } | ||||
|                 responseBodyAsStream.close(); | ||||
| 
 | ||||
|             } catch (IOException io) { | ||||
| @ -252,7 +244,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public Uri getBaseFilesWebDavUri(){ | ||||
|     public Uri getBaseFilesWebDavUri() { | ||||
|         return Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0); | ||||
|     } | ||||
| 
 | ||||
| @ -260,7 +252,7 @@ public class OwnCloudClient extends HttpClient { | ||||
|         return mCredentials instanceof OwnCloudAnonymousCredentials | ||||
|                 ? Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0) | ||||
|                 : Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0 + AccountUtils.getUserId( | ||||
|                         mAccount.getSavedAccount(), getContext() | ||||
|                 mAccount.getSavedAccount(), getContext() | ||||
|                 ) | ||||
|         ); | ||||
|     } | ||||
| @ -269,14 +261,18 @@ public class OwnCloudClient extends HttpClient { | ||||
|         return mCredentials instanceof OwnCloudAnonymousCredentials | ||||
|                 ? Uri.parse(mBaseUri + WEBDAV_UPLOADS_PATH_4_0) | ||||
|                 : Uri.parse(mBaseUri + WEBDAV_UPLOADS_PATH_4_0 + AccountUtils.getUserId( | ||||
|                         mAccount.getSavedAccount(), getContext() | ||||
|                 mAccount.getSavedAccount(), getContext() | ||||
|                 ) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public Uri getBaseUri() { | ||||
|         return mBaseUri; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets the root URI to the ownCloud server. | ||||
|      * | ||||
|      * <p> | ||||
|      * Use with care. | ||||
|      * | ||||
|      * @param uri | ||||
| @ -288,14 +284,19 @@ public class OwnCloudClient extends HttpClient { | ||||
|         mBaseUri = uri; | ||||
|     } | ||||
| 
 | ||||
|     public Uri getBaseUri() { | ||||
|         return mBaseUri; | ||||
|     } | ||||
| 
 | ||||
|     public final OwnCloudCredentials getCredentials() { | ||||
|         return mCredentials; | ||||
|     } | ||||
| 
 | ||||
|     public void setCredentials(OwnCloudCredentials credentials) { | ||||
|         if (credentials != null) { | ||||
|             mCredentials = credentials; | ||||
|             mCredentials.applyTo(this); | ||||
|         } else { | ||||
|             clearCredentials(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void logCookie(Cookie cookie) { | ||||
|         Log_OC.d(TAG, "Cookie name: " + cookie.name()); | ||||
|         Log_OC.d(TAG, "       value: " + cookie.value()); | ||||
| @ -348,27 +349,27 @@ public class OwnCloudClient extends HttpClient { | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public void setOwnCloudVersion(OwnCloudVersion version) { | ||||
|         mVersion = version; | ||||
|     } | ||||
| 
 | ||||
|     public OwnCloudVersion getOwnCloudVersion() { | ||||
|         return mVersion; | ||||
|     } | ||||
| 
 | ||||
|     public void setAccount(OwnCloudAccount account) { | ||||
|         this.mAccount = account; | ||||
|     public void setOwnCloudVersion(OwnCloudVersion version) { | ||||
|         mVersion = version; | ||||
|     } | ||||
| 
 | ||||
|     public OwnCloudAccount getAccount() { | ||||
|         return mAccount; | ||||
|     } | ||||
| 
 | ||||
|     public void setAccount(OwnCloudAccount account) { | ||||
|         this.mAccount = account; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Checks the status code of an execution and decides if should be repeated with fresh credentials. | ||||
|      * | ||||
|      * <p> | ||||
|      * Invalidates current credentials if the request failed as anauthorized. | ||||
|      * | ||||
|      * <p> | ||||
|      * Refresh current credentials if possible, and marks a retry. | ||||
|      * | ||||
|      * @param status | ||||
| @ -416,10 +417,9 @@ public class OwnCloudClient extends HttpClient { | ||||
|      * Determines if credentials should be invalidated according the to the HTTPS status | ||||
|      * of a network request just performed. | ||||
|      * | ||||
|      * @param httpStatusCode    Result of the last request ran with the 'credentials' belows. | ||||
| 
 | ||||
|      * @return                  'True' if credentials should and might be invalidated, 'false' if shouldn't or | ||||
|      *                          cannot be invalidated with the given arguments. | ||||
|      * @param httpStatusCode Result of the last request ran with the 'credentials' belows. | ||||
|      * @return 'True' if credentials should and might be invalidated, 'false' if shouldn't or | ||||
|      * cannot be invalidated with the given arguments. | ||||
|      */ | ||||
|     private boolean shouldInvalidateAccountCredentials(int httpStatusCode) { | ||||
| 
 | ||||
| @ -437,10 +437,10 @@ public class OwnCloudClient extends HttpClient { | ||||
|     /** | ||||
|      * Invalidates credentials stored for the given account in the system  {@link AccountManager} and in | ||||
|      * current {@link OwnCloudClientManagerFactory#getDefaultSingleton()} instance. | ||||
|      * | ||||
|      * <p> | ||||
|      * {@link #shouldInvalidateAccountCredentials(int)} should be called first. | ||||
|      * | ||||
|      * @return                  'True' if invalidation was successful, 'false' otherwise. | ||||
|      * @return 'True' if invalidation was successful, 'false' otherwise. | ||||
|      */ | ||||
|     private boolean invalidateAccountCredentials() { | ||||
|         AccountManager am = AccountManager.get(getContext()); | ||||
| @ -462,6 +462,7 @@ public class OwnCloudClient extends HttpClient { | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the redirection is to an identity provider such as SAML or wayf | ||||
|      * | ||||
|      * @return true if the redirection location includes SAML or wayf, false otherwise | ||||
|      */ | ||||
|     private boolean isIdPRedirection() { | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -43,29 +43,28 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class OwnCloudClientFactory { | ||||
|      | ||||
| 
 | ||||
|     final private static String TAG = OwnCloudClientFactory.class.getSimpleName(); | ||||
| 
 | ||||
|     /** | ||||
|      * Creates a OwnCloudClient setup for an ownCloud account | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * @param account                       The ownCloud account | ||||
|      * @param appContext                    Android application context | ||||
|      * @param currentActivity               Caller {@link Activity} | ||||
|      * @return                              A OwnCloudClient object ready to be used | ||||
|      * @throws AuthenticatorException       If the authenticator failed to get the authorization | ||||
|      *                                      token for the account. | ||||
|      * @throws OperationCanceledException   If the authenticator operation was cancelled while | ||||
|      *                                      getting the authorization token for the account. | ||||
|      * @throws IOException                  If there was some I/O error while getting the | ||||
|      *                                      authorization token for the account. | ||||
|      * @throws AccountNotFoundException     If 'account' is unknown for the AccountManager | ||||
|      * | ||||
|      * @param account         The ownCloud account | ||||
|      * @param appContext      Android application context | ||||
|      * @param currentActivity Caller {@link Activity} | ||||
|      * @return A OwnCloudClient object ready to be used | ||||
|      * @throws AuthenticatorException     If the authenticator failed to get the authorization | ||||
|      *                                    token for the account. | ||||
|      * @throws OperationCanceledException If the authenticator operation was cancelled while | ||||
|      *                                    getting the authorization token for the account. | ||||
|      * @throws IOException                If there was some I/O error while getting the | ||||
|      *                                    authorization token for the account. | ||||
|      * @throws AccountNotFoundException   If 'account' is unknown for the AccountManager | ||||
|      */ | ||||
|     public static OwnCloudClient createOwnCloudClient (Account account, Context appContext, | ||||
|                                                        Activity currentActivity) | ||||
|     public static OwnCloudClient createOwnCloudClient(Account account, Context appContext, | ||||
|                                                       Activity currentActivity) | ||||
|             throws OperationCanceledException, AuthenticatorException, IOException, | ||||
|             AccountNotFoundException { | ||||
|         Uri baseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(appContext, account)); | ||||
| @ -79,57 +78,60 @@ public class OwnCloudClientFactory { | ||||
| 
 | ||||
|         String username = AccountUtils.getUsernameForAccount(account); | ||||
|         if (isOauth2) {    // TODO avoid a call to getUserData here | ||||
|             AccountManagerFuture<Bundle> future =  am.getAuthToken( | ||||
|                 account, | ||||
|                 AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), | ||||
|                 null, | ||||
|                 currentActivity, | ||||
|                 null, | ||||
|                 null); | ||||
|             AccountManagerFuture<Bundle> future = am.getAuthToken( | ||||
|                     account, | ||||
|                     AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), | ||||
|                     null, | ||||
|                     currentActivity, | ||||
|                     null, | ||||
|                     null); | ||||
| 
 | ||||
|             Bundle result = future.getResult(); | ||||
|             String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); | ||||
|             if (accessToken == null) throw new AuthenticatorException("WTF!"); | ||||
|             if (accessToken == null) { | ||||
|                 throw new AuthenticatorException("WTF!"); | ||||
|             } | ||||
|             client.setCredentials( | ||||
|                 OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken) | ||||
|                     OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken) | ||||
|             ); | ||||
| 
 | ||||
|         } else if (isSamlSso) {    // TODO avoid a call to getUserData here | ||||
|             AccountManagerFuture<Bundle> future =  am.getAuthToken( | ||||
|                account, | ||||
|                AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type), | ||||
|                 null, | ||||
|                 currentActivity, | ||||
|                 null, | ||||
|                 null); | ||||
|             AccountManagerFuture<Bundle> future = am.getAuthToken( | ||||
|                     account, | ||||
|                     AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type), | ||||
|                     null, | ||||
|                     currentActivity, | ||||
|                     null, | ||||
|                     null); | ||||
| 
 | ||||
|             Bundle result = future.getResult(); | ||||
|             String accessToken = result.getString(AccountManager.KEY_AUTHTOKEN); | ||||
|             if (accessToken == null) throw new AuthenticatorException("WTF!"); | ||||
|             if (accessToken == null) { | ||||
|                 throw new AuthenticatorException("WTF!"); | ||||
|             } | ||||
|             client.setCredentials( | ||||
|                 OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken) | ||||
|                     OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken) | ||||
|             ); | ||||
| 
 | ||||
| 
 | ||||
|         } else { | ||||
|             AccountManagerFuture<Bundle> future =  am.getAuthToken( | ||||
|                 account, | ||||
|                 AccountTypeUtils.getAuthTokenTypePass(account.type), | ||||
|                 null, | ||||
|                 currentActivity, | ||||
|                 null, | ||||
|                 null | ||||
|             AccountManagerFuture<Bundle> future = am.getAuthToken( | ||||
|                     account, | ||||
|                     AccountTypeUtils.getAuthTokenTypePass(account.type), | ||||
|                     null, | ||||
|                     currentActivity, | ||||
|                     null, | ||||
|                     null | ||||
|             ); | ||||
| 
 | ||||
|             Bundle result = future.getResult(); | ||||
|             String password = result.getString(AccountManager.KEY_AUTHTOKEN); | ||||
|             OwnCloudVersion version = AccountUtils.getServerVersionForAccount(account, appContext); | ||||
|             client.setCredentials( | ||||
|                 OwnCloudCredentialsFactory.newBasicCredentials( | ||||
|                     username, | ||||
|                     password, | ||||
|                     (version != null && version.isPreemptiveAuthenticationPreferred()) | ||||
|                 ) | ||||
|                     OwnCloudCredentialsFactory.newBasicCredentials( | ||||
|                             username, | ||||
|                             password, | ||||
|                             (version != null && version.isPreemptiveAuthenticationPreferred()) | ||||
|                     ) | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
| @ -142,10 +144,10 @@ public class OwnCloudClientFactory { | ||||
|     /** | ||||
|      * Creates a OwnCloudClient to access a URL and sets the desired parameters for ownCloud | ||||
|      * client connections. | ||||
|      *  | ||||
|      * @param uri       URL to the ownCloud server; BASE ENTRY POINT, not WebDavPATH | ||||
|      * @param context   Android context where the OwnCloudClient is being created. | ||||
|      * @return          A OwnCloudClient object ready to be used | ||||
|      * | ||||
|      * @param uri     URL to the ownCloud server; BASE ENTRY POINT, not WebDavPATH | ||||
|      * @param context Android context where the OwnCloudClient is being created. | ||||
|      * @return A OwnCloudClient object ready to be used | ||||
|      */ | ||||
|     public static OwnCloudClient createOwnCloudClient(Uri uri, Context context, | ||||
|                                                       boolean followRedirects) { | ||||
| @ -154,7 +156,7 @@ public class OwnCloudClientFactory { | ||||
|         client.setFollowRedirects(followRedirects); | ||||
| 
 | ||||
|         client.setContext(context); | ||||
|          | ||||
| 
 | ||||
|         return client; | ||||
|     } | ||||
| } | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,17 +24,17 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import android.accounts.AuthenticatorException; | ||||
| import android.accounts.OperationCanceledException; | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| /** | ||||
|  * Manager to create and reuse OwnCloudClient instances to access remote OC servers.  | ||||
|  *  | ||||
|  * Manager to create and reuse OwnCloudClient instances to access remote OC servers. | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  * @author masensio | ||||
|  * @author Christian Schabesberger | ||||
| @ -42,13 +42,13 @@ import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundExce | ||||
| 
 | ||||
| public interface OwnCloudClientManager { | ||||
| 
 | ||||
| 	OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws AccountNotFoundException, | ||||
| 			OperationCanceledException, AuthenticatorException, | ||||
|     OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws AccountNotFoundException, | ||||
|             OperationCanceledException, AuthenticatorException, | ||||
|             IOException; | ||||
|      | ||||
| 
 | ||||
|     OwnCloudClient removeClientFor(OwnCloudAccount account); | ||||
| 
 | ||||
|     void saveAllClients(Context context, String accountType) | ||||
| 			throws AccountNotFoundException, AuthenticatorException,  | ||||
| 			IOException, OperationCanceledException; | ||||
|             throws AccountNotFoundException, AuthenticatorException, | ||||
|             IOException, OperationCanceledException; | ||||
| } | ||||
| @ -25,16 +25,8 @@ package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| public class OwnCloudClientManagerFactory { | ||||
| 
 | ||||
|     public static enum Policy { | ||||
|         ALWAYS_NEW_CLIENT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING | ||||
|     } | ||||
| 
 | ||||
|     private static Policy sDefaultPolicy = Policy.ALWAYS_NEW_CLIENT; | ||||
| 
 | ||||
|     private static OwnCloudClientManager sDefaultSingleton; | ||||
| 
 | ||||
|     private static String sUserAgent; | ||||
| 
 | ||||
|     public static OwnCloudClientManager newDefaultOwnCloudClientManager() { | ||||
| @ -78,26 +70,32 @@ public class OwnCloudClientManagerFactory { | ||||
|         sDefaultPolicy = policy; | ||||
|     } | ||||
| 
 | ||||
|     public static void setUserAgent(String userAgent) { | ||||
|         sUserAgent = userAgent; | ||||
|     } | ||||
| 
 | ||||
|     public static String getUserAgent() { | ||||
|         return sUserAgent; | ||||
|     } | ||||
| 
 | ||||
|     public static void setUserAgent(String userAgent) { | ||||
|         sUserAgent = userAgent; | ||||
|     } | ||||
| 
 | ||||
|     private static boolean defaultSingletonMustBeUpdated(Policy policy) { | ||||
|         if (sDefaultSingleton == null) { | ||||
|             return false; | ||||
|         } | ||||
|         if (policy == Policy.ALWAYS_NEW_CLIENT && | ||||
|             !(sDefaultSingleton instanceof SimpleFactoryManager)) { | ||||
|                 !(sDefaultSingleton instanceof SimpleFactoryManager)) { | ||||
|             return true; | ||||
|         } | ||||
|         if (policy == Policy.SINGLE_SESSION_PER_ACCOUNT && | ||||
|             !(sDefaultSingleton instanceof SingleSessionManager)) { | ||||
|                 !(sDefaultSingleton instanceof SingleSessionManager)) { | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     public static enum Policy { | ||||
|         ALWAYS_NEW_CLIENT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT, | ||||
|         SINGLE_SESSION_PER_ACCOUNT_IF_SERVER_SUPPORTS_SERVER_MONITORING | ||||
|     } | ||||
| } | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,13 +24,11 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common; | ||||
| 
 | ||||
| 
 | ||||
| import android.accounts.AuthenticatorException; | ||||
| import android.accounts.OperationCanceledException; | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| @ -46,16 +44,16 @@ public class SimpleFactoryManager implements OwnCloudClientManager { | ||||
|         Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : "); | ||||
| 
 | ||||
|         OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient( | ||||
|             account.getBaseUri(), | ||||
|             context.getApplicationContext(), | ||||
|             true); | ||||
|                 account.getBaseUri(), | ||||
|                 context.getApplicationContext(), | ||||
|                 true); | ||||
| 
 | ||||
|         Log_OC.v(TAG, "    new client {" + | ||||
|             (account.getName() != null ? | ||||
|                 account.getName() : | ||||
|                 AccountUtils.buildAccountName(account.getBaseUri(), "") | ||||
|                 (account.getName() != null ? | ||||
|                         account.getName() : | ||||
|                         AccountUtils.buildAccountName(account.getBaseUri(), "") | ||||
| 
 | ||||
|             ) + ", " + client.hashCode() + "}"); | ||||
|                 ) + ", " + client.hashCode() + "}"); | ||||
| 
 | ||||
|         if (account.getCredentials() == null) { | ||||
|             account.loadCredentials(context); | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -43,7 +43,7 @@ import java.util.concurrent.ConcurrentMap; | ||||
| 
 | ||||
| /** | ||||
|  * Implementation of {@link OwnCloudClientManager} | ||||
|  * | ||||
|  * <p> | ||||
|  * TODO check multithreading safety | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -57,11 +57,10 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|     private static final String TAG = SingleSessionManager.class.getSimpleName(); | ||||
| 
 | ||||
|     private ConcurrentMap<String, OwnCloudClient> mClientsWithKnownUsername = | ||||
|         new ConcurrentHashMap<>(); | ||||
|             new ConcurrentHashMap<>(); | ||||
| 
 | ||||
|     private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername = | ||||
|         new ConcurrentHashMap<>(); | ||||
| 
 | ||||
|             new ConcurrentHashMap<>(); | ||||
| 
 | ||||
|     @Override | ||||
|     public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws OperationCanceledException, | ||||
| @ -77,9 +76,9 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|         OwnCloudClient client = null; | ||||
|         String accountName = account.getName(); | ||||
|         String sessionName = account.getCredentials() == null ? "" : | ||||
|             AccountUtils.buildAccountName( | ||||
|                 account.getBaseUri(), | ||||
|                 account.getCredentials().getAuthToken()); | ||||
|                 AccountUtils.buildAccountName( | ||||
|                         account.getBaseUri(), | ||||
|                         account.getCredentials().getAuthToken()); | ||||
| 
 | ||||
|         if (accountName != null) { | ||||
|             client = mClientsWithKnownUsername.get(accountName); | ||||
| @ -110,9 +109,9 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|         if (client == null) { | ||||
|             // no client to reuse - create a new one | ||||
|             client = OwnCloudClientFactory.createOwnCloudClient( | ||||
|                 account.getBaseUri(), | ||||
|                 context.getApplicationContext(), | ||||
|                 true);    // TODO remove dependency on OwnCloudClientFactory | ||||
|                     account.getBaseUri(), | ||||
|                     context.getApplicationContext(), | ||||
|                     true);    // TODO remove dependency on OwnCloudClientFactory | ||||
|             client.setAccount(account); | ||||
|             client.setContext(context); | ||||
|             client.setOwnCloudClientManager(this); | ||||
| @ -152,7 +151,6 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|         return client; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public OwnCloudClient removeClientFor(OwnCloudAccount account) { | ||||
|         if (Log.isLoggable(TAG, Log.DEBUG)) { | ||||
| @ -187,7 +185,6 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void saveAllClients(Context context, String accountType) { | ||||
| 
 | ||||
| @ -202,9 +199,9 @@ public class SingleSessionManager implements OwnCloudClientManager { | ||||
|             accountName = accountNames.next(); | ||||
|             account = new Account(accountName, accountType); | ||||
|             AccountUtils.saveClient( | ||||
|                 mClientsWithKnownUsername.get(accountName), | ||||
|                 account, | ||||
|                 context); | ||||
|                     mClientsWithKnownUsername.get(accountName), | ||||
|                     account, | ||||
|                     context); | ||||
|         } | ||||
| 
 | ||||
|         if (Log.isLoggable(TAG, Log.DEBUG)) { | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -33,17 +33,17 @@ public class AccountTypeUtils { | ||||
|     public static String getAuthTokenTypePass(String accountType) { | ||||
|         return accountType + ".password"; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public static String getAuthTokenTypeAccessToken(String accountType) { | ||||
|         return accountType  + ".oauth2.access_token"; | ||||
|         return accountType + ".oauth2.access_token"; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public static String getAuthTokenTypeRefreshToken(String accountType) { | ||||
|         return accountType  + ".oauth2.refresh_token"; | ||||
|         return accountType + ".oauth2.refresh_token"; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public static String getAuthTokenTypeSamlSessionCookie(String accountType) { | ||||
|         return accountType  +  ".saml.web_sso.session_cookie"; | ||||
|         return accountType + ".saml.web_sso.session_cookie"; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,23 +1,23 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *   Copyright (C) 2012  Bartek Przybylski | ||||
|  *    | ||||
|  * | ||||
|  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  *   of this software and associated documentation files (the "Software"), to deal | ||||
|  *   in the Software without restriction, including without limitation the rights | ||||
|  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  *   copies of the Software, and to permit persons to whom the Software is | ||||
|  *   furnished to do so, subject to the following conditions: | ||||
|  *    | ||||
|  * | ||||
|  *   The above copyright notice and this permission notice shall be included in | ||||
|  *   all copies or substantial portions of the Software. | ||||
|  *    | ||||
|  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -39,13 +39,12 @@ import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| import okhttp3.Cookie; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import okhttp3.Cookie; | ||||
| 
 | ||||
| public class AccountUtils { | ||||
| 
 | ||||
|     private static final String TAG = AccountUtils.class.getSimpleName(); | ||||
| @ -53,13 +52,13 @@ public class AccountUtils { | ||||
|     /** | ||||
|      * Constructs full url to host and webdav resource basing on host version | ||||
|      * | ||||
|      * @param context               Valid Android {@link Context}, needed to access the {@link AccountManager} | ||||
|      * @param account               A stored ownCloud {@link Account} | ||||
|      * @return                      Full URL to WebDAV endpoint in the server corresponding to 'account'. | ||||
|      * @param context Valid Android {@link Context}, needed to access the {@link AccountManager} | ||||
|      * @param account A stored ownCloud {@link Account} | ||||
|      * @return Full URL to WebDAV endpoint in the server corresponding to 'account'. | ||||
|      * @throws AccountNotFoundException When 'account' is unknown for the AccountManager | ||||
|      */ | ||||
|     public static String getWebDavUrlForAccount(Context context, Account account) | ||||
|         throws AccountNotFoundException { | ||||
|             throws AccountNotFoundException { | ||||
|         String webDavUrlForAccount = ""; | ||||
| 
 | ||||
|         try { | ||||
| @ -80,19 +79,20 @@ public class AccountUtils { | ||||
|     /** | ||||
|      * Extracts url server from the account | ||||
|      * | ||||
|      * @param context               Valid Android {@link Context}, needed to access the {@link AccountManager} | ||||
|      * @param account               A stored ownCloud {@link Account} | ||||
|      * @return                      Full URL to the server corresponding to 'account', ending in the base path | ||||
|      *                              common to all API endpoints. | ||||
|      * @param context Valid Android {@link Context}, needed to access the {@link AccountManager} | ||||
|      * @param account A stored ownCloud {@link Account} | ||||
|      * @return Full URL to the server corresponding to 'account', ending in the base path | ||||
|      * common to all API endpoints. | ||||
|      * @throws AccountNotFoundException When 'account' is unknown for the AccountManager | ||||
|      */ | ||||
|     public static String getBaseUrlForAccount(Context context, Account account) | ||||
|         throws AccountNotFoundException { | ||||
|             throws AccountNotFoundException { | ||||
|         AccountManager ama = AccountManager.get(context.getApplicationContext()); | ||||
|         String baseurl = ama.getUserData(account, Constants.KEY_OC_BASE_URL); | ||||
| 
 | ||||
|         if (baseurl == null) | ||||
|         if (baseurl == null) { | ||||
|             throw new AccountNotFoundException(account, "Account not found", null); | ||||
|         } | ||||
| 
 | ||||
|         return baseurl; | ||||
|     } | ||||
| @ -116,8 +116,8 @@ public class AccountUtils { | ||||
|     /** | ||||
|      * Get the stored server version corresponding to an OC account. | ||||
|      * | ||||
|      * @param account   An OC account | ||||
|      * @param context   Application context | ||||
|      * @param account An OC account | ||||
|      * @param context Application context | ||||
|      * @return Version of the OC server, according to last check | ||||
|      */ | ||||
|     public static OwnCloudVersion getServerVersionForAccount(Account account, Context context) { | ||||
| @ -140,7 +140,7 @@ public class AccountUtils { | ||||
|      * @throws OperationCanceledException | ||||
|      */ | ||||
|     public static OwnCloudCredentials getCredentialsForAccount(Context context, Account account) | ||||
|         throws OperationCanceledException, AuthenticatorException, IOException { | ||||
|             throws OperationCanceledException, AuthenticatorException, IOException { | ||||
| 
 | ||||
|         OwnCloudCredentials credentials; | ||||
|         AccountManager am = AccountManager.get(context); | ||||
| @ -158,30 +158,30 @@ public class AccountUtils { | ||||
| 
 | ||||
|         if (isOauth2) { | ||||
|             String accessToken = am.blockingGetAuthToken( | ||||
|                 account, | ||||
|                 AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), | ||||
|                 false); | ||||
|                     account, | ||||
|                     AccountTypeUtils.getAuthTokenTypeAccessToken(account.type), | ||||
|                     false); | ||||
| 
 | ||||
|             credentials = OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken); | ||||
| 
 | ||||
|         } else if (isSamlSso) { | ||||
|             String accessToken = am.blockingGetAuthToken( | ||||
|                 account, | ||||
|                 AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type), | ||||
|                 false); | ||||
|                     account, | ||||
|                     AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(account.type), | ||||
|                     false); | ||||
| 
 | ||||
|             credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(username, accessToken); | ||||
| 
 | ||||
|         } else { | ||||
|             String password = am.blockingGetAuthToken( | ||||
|                 account, | ||||
|                 AccountTypeUtils.getAuthTokenTypePass(account.type), | ||||
|                 false); | ||||
|                     account, | ||||
|                     AccountTypeUtils.getAuthTokenTypePass(account.type), | ||||
|                     false); | ||||
| 
 | ||||
|             credentials = OwnCloudCredentialsFactory.newBasicCredentials( | ||||
|                 username, | ||||
|                 password, | ||||
|                 version.isPreemptiveAuthenticationPreferred() | ||||
|                     username, | ||||
|                     password, | ||||
|                     version.isPreemptiveAuthenticationPreferred() | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
| @ -190,8 +190,9 @@ public class AccountUtils { | ||||
| 
 | ||||
|     /** | ||||
|      * Get the user id corresponding to an OC account. | ||||
|      * | ||||
|      * @param account ownCloud account | ||||
|      * @return        user id | ||||
|      * @return user id | ||||
|      */ | ||||
|     public static String getUserId(Account account, Context context) { | ||||
|         AccountManager accountMgr = AccountManager.get(context); | ||||
| @ -232,7 +233,7 @@ public class AccountUtils { | ||||
|             String cookiesString = client.getCookiesString(); | ||||
|             if (!"".equals(cookiesString)) { | ||||
|                 ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString); | ||||
|                  Log_OC.d(TAG, "Saving Cookies: "+ cookiesString ); | ||||
|                 Log_OC.d(TAG, "Saving Cookies: " + cookiesString); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -240,9 +241,9 @@ public class AccountUtils { | ||||
|     /** | ||||
|      * Restore the client cookies persisted in an account stored in the system AccountManager. | ||||
|      * | ||||
|      * @param account           Stored account. | ||||
|      * @param client            Client to restore cookies in. | ||||
|      * @param context           Android context used to access the system AccountManager. | ||||
|      * @param account Stored account. | ||||
|      * @param client  Client to restore cookies in. | ||||
|      * @param context Android context used to access the system AccountManager. | ||||
|      */ | ||||
|     public static void restoreCookies(Account account, OwnCloudClient client, Context context) { | ||||
|         if (account == null) { | ||||
| @ -260,10 +261,12 @@ public class AccountUtils { | ||||
|             if (cookiesString != null) { | ||||
|                 String[] rawCookies = cookiesString.split(";"); | ||||
|                 List<Cookie> cookieList = new ArrayList<>(rawCookies.length); | ||||
|                 for(String rawCookie : rawCookies) { | ||||
|                 for (String rawCookie : rawCookies) { | ||||
|                     rawCookie = rawCookie.replace(" ", ""); | ||||
|                     final int equalPos = rawCookie.indexOf('='); | ||||
|                     if (equalPos == -1) continue; | ||||
|                     if (equalPos == -1) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     cookieList.add(new Cookie.Builder() | ||||
|                             .name(rawCookie.substring(0, equalPos)) | ||||
|                             .value(rawCookie.substring(equalPos + 1)) | ||||
|  | ||||
| @ -26,7 +26,6 @@ package com.owncloud.android.lib.common.authentication; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| 
 | ||||
| import okhttp3.Credentials; | ||||
| 
 | ||||
| public class OwnCloudBasicCredentials implements OwnCloudCredentials { | ||||
|  | ||||
| @ -39,7 +39,7 @@ public class OwnCloudCredentialsFactory { | ||||
|     } | ||||
| 
 | ||||
|     public static OwnCloudCredentials newBasicCredentials( | ||||
|         String username, String password, boolean preemptiveMode | ||||
|             String username, String password, boolean preemptiveMode | ||||
|     ) { | ||||
|         return new OwnCloudBasicCredentials(username, password, preemptiveMode); | ||||
|     } | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -32,14 +32,13 @@ public class BearerCredentials { | ||||
| 
 | ||||
|     public static final int HASH_SEED = 17; | ||||
|     public static final int HASH_OFFSET = 37; | ||||
|      | ||||
| 
 | ||||
|     private String mAccessToken; | ||||
|      | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * The constructor with the bearer token | ||||
|      * | ||||
|      * @param token     The bearer token | ||||
|      * @param token The bearer token | ||||
|      */ | ||||
|     public BearerCredentials(String token) { | ||||
|         /*if (token == null) { | ||||
| @ -48,21 +47,19 @@ public class BearerCredentials { | ||||
|         mAccessToken = (token == null) ? "" : token; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the access token | ||||
|      * | ||||
|      * @return      The access token | ||||
|      * @return The access token | ||||
|      */ | ||||
|     public String getAccessToken() { | ||||
|         return mAccessToken; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Get this object string. | ||||
|      * | ||||
|      * @return  The access token | ||||
|      * @return The access token | ||||
|      */ | ||||
|     public String toString() { | ||||
|         return mAccessToken; | ||||
| @ -74,19 +71,22 @@ public class BearerCredentials { | ||||
|      * @return The hash code of the access token | ||||
|      */ | ||||
|     public int hashCode() { | ||||
|        return HASH_SEED * HASH_OFFSET + mAccessToken.hashCode(); | ||||
|         return HASH_SEED * HASH_OFFSET + mAccessToken.hashCode(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * These credentials are assumed equal if accessToken is the same. | ||||
|      * | ||||
|      * @param   o   The other object to compare with. | ||||
|      * | ||||
|      * @return      'True' if the object is equivalent. | ||||
|      * @param o The other object to compare with. | ||||
|      * @return 'True' if the object is equivalent. | ||||
|      */ | ||||
|     public boolean equals(Object o) { | ||||
|         if (o == null) return false; | ||||
|         if (this == o) return true; | ||||
|         if (o == null) { | ||||
|             return false; | ||||
|         } | ||||
|         if (this == o) { | ||||
|             return true; | ||||
|         } | ||||
|         if (this.getClass().equals(o.getClass())) { | ||||
|             BearerCredentials that = (BearerCredentials) o; | ||||
|             if (mAccessToken.equals(that.mAccessToken)) { | ||||
|  | ||||
| @ -26,34 +26,34 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| /**  | ||||
| /** | ||||
|  * Constant values for OAuth 2 protocol. | ||||
|  *  | ||||
|  * <p> | ||||
|  * Includes required and optional parameter NAMES used in the 'authorization code' grant type. | ||||
|  */ | ||||
| 
 | ||||
| public class OAuth2Constants { | ||||
|      | ||||
| 
 | ||||
|     /// Parameters to send to the Authorization Endpoint | ||||
|     public static final String KEY_RESPONSE_TYPE = "response_type"; | ||||
|     public static final String KEY_REDIRECT_URI = "redirect_uri"; | ||||
|     public static final String KEY_CLIENT_ID = "client_id"; | ||||
|     public static final String KEY_SCOPE = "scope"; | ||||
|     public static final String KEY_STATE = "state";  | ||||
|      | ||||
|     public static final String KEY_STATE = "state"; | ||||
| 
 | ||||
|     /// Additional parameters to send to the Token Endpoint | ||||
|     public static final String KEY_GRANT_TYPE = "grant_type"; | ||||
|     public static final String KEY_CODE = "code"; | ||||
| 
 | ||||
|     // Used to get the Access Token using Refresh Token | ||||
|     public static final String OAUTH2_REFRESH_TOKEN_GRANT_TYPE = "refresh_token"; | ||||
|      | ||||
| 
 | ||||
|     /// Parameters received in an OK response from the Token Endpoint  | ||||
|     public static final String KEY_ACCESS_TOKEN = "access_token"; | ||||
|     public static final String KEY_TOKEN_TYPE = "token_type"; | ||||
|     public static final String KEY_EXPIRES_IN = "expires_in"; | ||||
|     public static final String KEY_REFRESH_TOKEN = "refresh_token"; | ||||
|      | ||||
| 
 | ||||
|     /// Parameters in an ERROR response | ||||
|     public static final String KEY_ERROR = "error"; | ||||
|     public static final String KEY_ERROR_DESCRIPTION = "error_description"; | ||||
|  | ||||
| @ -29,42 +29,37 @@ package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| 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 okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| 
 | ||||
| 
 | ||||
| public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, String>> { | ||||
|      | ||||
| 
 | ||||
|     private final String mAccessTokenEndpointPath; | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
|     private String mGrantType; | ||||
|     private String mCode; | ||||
|     private String mClientId; | ||||
|     private String mClientSecret; | ||||
|     private String mRedirectUri; | ||||
|     private final String mAccessTokenEndpointPath; | ||||
| 
 | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
| 
 | ||||
| 
 | ||||
|     public OAuth2GetAccessTokenOperation( | ||||
|         String grantType, | ||||
|         String code, | ||||
|         String clientId, | ||||
|         String secretId, | ||||
|         String redirectUri, | ||||
|         String accessTokenEndpointPath | ||||
|             String grantType, | ||||
|             String code, | ||||
|             String clientId, | ||||
|             String secretId, | ||||
|             String redirectUri, | ||||
|             String accessTokenEndpointPath | ||||
|     ) { | ||||
|         mClientId = clientId; | ||||
|         mClientSecret = secretId; | ||||
| @ -73,9 +68,9 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, S | ||||
|         mCode = code; | ||||
| 
 | ||||
|         mAccessTokenEndpointPath = | ||||
|             accessTokenEndpointPath != null ? | ||||
|                 accessTokenEndpointPath : | ||||
|                 OwnCloudOAuth2Provider.ACCESS_TOKEN_ENDPOINT_PATH | ||||
|                 accessTokenEndpointPath != null ? | ||||
|                         accessTokenEndpointPath : | ||||
|                         OwnCloudOAuth2Provider.ACCESS_TOKEN_ENDPOINT_PATH | ||||
|         ; | ||||
| 
 | ||||
|         mResponseParser = new OAuth2ResponseParser(); | ||||
| @ -84,7 +79,7 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, S | ||||
|     @Override | ||||
|     protected RemoteOperationResult run(OwnCloudClient client) { | ||||
|         RemoteOperationResult<Map<String, String>> result = null; | ||||
|          | ||||
| 
 | ||||
|         try { | ||||
| 
 | ||||
|             final RequestBody requestBody = new MultipartBody.Builder() | ||||
| @ -116,7 +111,7 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, S | ||||
|             if (response != null && response.length() > 0) { | ||||
|                 JSONObject tokenJson = new JSONObject(response); | ||||
|                 Map<String, String> accessTokenResult = | ||||
|                     mResponseParser.parseAccessTokenResult(tokenJson); | ||||
|                         mResponseParser.parseAccessTokenResult(tokenJson); | ||||
|                 if (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null || | ||||
|                         accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) { | ||||
|                     result = new RemoteOperationResult<>(ResultCode.OAUTH2_ERROR); | ||||
| @ -133,7 +128,7 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, S | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             result = new RemoteOperationResult<>(e); | ||||
|              | ||||
| 
 | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -31,36 +31,35 @@ public interface OAuth2Provider { | ||||
|     /** | ||||
|      * {@link OAuth2RequestBuilder} implementation for this provider. | ||||
|      * | ||||
|      * @return      {@link OAuth2RequestBuilder} implementation. | ||||
|      * @return {@link OAuth2RequestBuilder} implementation. | ||||
|      */ | ||||
|     OAuth2RequestBuilder getOperationBuilder(); | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set configuration of the client that will use this {@link OAuth2Provider} | ||||
|      * @param oAuth2ClientConfiguration     Configuration of the client that will use this {@link OAuth2Provider} | ||||
|      */ | ||||
|     void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration); | ||||
| 
 | ||||
|     /** | ||||
|      * Configuration of the client that is using this {@link OAuth2Provider} | ||||
|      * return                   Configuration of the client that is usinng this {@link OAuth2Provider} | ||||
|      */ | ||||
|     OAuth2ClientConfiguration getClientConfiguration(); | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set base URI to authorization server. | ||||
|      * Set configuration of the client that will use this {@link OAuth2Provider} | ||||
|      * | ||||
|      * @param authorizationServerUri        Set base URL to authorization server. | ||||
|      * @param oAuth2ClientConfiguration Configuration of the client that will use this {@link OAuth2Provider} | ||||
|      */ | ||||
|     void setAuthorizationServerUri(String authorizationServerUri); | ||||
|     void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration); | ||||
| 
 | ||||
|     /** | ||||
|      * base URI to authorization server. | ||||
|      * | ||||
|      * @return      Base URL to authorization server. | ||||
|      * @return Base URL to authorization server. | ||||
|      */ | ||||
|     String getAuthorizationServerUri(); | ||||
| 
 | ||||
|     /** | ||||
|      * Set base URI to authorization server. | ||||
|      * | ||||
|      * @param authorizationServerUri Set base URL to authorization server. | ||||
|      */ | ||||
|     void setAuthorizationServerUri(String authorizationServerUri); | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -26,7 +26,6 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| @ -36,20 +35,13 @@ public class OAuth2ProvidersRegistry { | ||||
| 
 | ||||
|     private OAuth2Provider mDefaultProvider = null; | ||||
| 
 | ||||
|     private OAuth2ProvidersRegistry () { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom | ||||
|      */ | ||||
|     private static class LazyHolder { | ||||
|         private static final OAuth2ProvidersRegistry INSTANCE = new OAuth2ProvidersRegistry(); | ||||
|     private OAuth2ProvidersRegistry() { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Singleton accesor. | ||||
|      * | ||||
|      * @return     Singleton isntance of {@link OAuth2ProvidersRegistry} | ||||
|      * @return Singleton isntance of {@link OAuth2ProvidersRegistry} | ||||
|      */ | ||||
|     public static OAuth2ProvidersRegistry getInstance() { | ||||
|         return LazyHolder.INSTANCE; | ||||
| @ -58,8 +50,8 @@ public class OAuth2ProvidersRegistry { | ||||
|     /** | ||||
|      * Register an {@link OAuth2Provider} with the name passed as parameter. | ||||
|      * | ||||
|      * @param name              Name to bind 'oAuthProvider' in the registry. | ||||
|      * @param oAuth2Provider    An {@link OAuth2Provider} instance to keep in the registry. | ||||
|      * @param name           Name to bind 'oAuthProvider' in the registry. | ||||
|      * @param oAuth2Provider An {@link OAuth2Provider} instance to keep in the registry. | ||||
|      * @throws IllegalArgumentException if 'name' or 'oAuthProvider' are null. | ||||
|      */ | ||||
|     public void registerProvider(String name, OAuth2Provider oAuth2Provider) { | ||||
| @ -89,7 +81,7 @@ public class OAuth2ProvidersRegistry { | ||||
|     /** | ||||
|      * Get default {@link OAuth2Provider}. | ||||
|      * | ||||
|      * @return      Default provider, or NULL if there is no provider. | ||||
|      * @return Default provider, or NULL if there is no provider. | ||||
|      */ | ||||
|     public OAuth2Provider getProvider() { | ||||
|         return mDefaultProvider; | ||||
| @ -98,8 +90,8 @@ public class OAuth2ProvidersRegistry { | ||||
|     /** | ||||
|      * Get {@link OAuth2Provider} registered with the name passed as parameter. | ||||
|      * | ||||
|      * @param name  Name used to register the desired {@link OAuth2Provider} | ||||
|      * @return      {@link OAuth2Provider} registered with the name 'name' | ||||
|      * @param name Name used to register the desired {@link OAuth2Provider} | ||||
|      * @return {@link OAuth2Provider} registered with the name 'name' | ||||
|      */ | ||||
|     public OAuth2Provider getProvider(String name) { | ||||
|         return mProviders.get(name); | ||||
| @ -108,8 +100,8 @@ public class OAuth2ProvidersRegistry { | ||||
|     /** | ||||
|      * Sets the {@link OAuth2Provider} registered with the name passed as parameter as the default provider | ||||
|      * | ||||
|      * @param name  Name used to register the {@link OAuth2Provider} to set as default. | ||||
|      * @return      {@link OAuth2Provider} set as default, or NULL if no provider was registered with 'name'. | ||||
|      * @param name Name used to register the {@link OAuth2Provider} to set as default. | ||||
|      * @return {@link OAuth2Provider} set as default, or NULL if no provider was registered with 'name'. | ||||
|      */ | ||||
|     public OAuth2Provider setDefaultProvider(String name) { | ||||
|         OAuth2Provider toDefault = mProviders.get(name); | ||||
| @ -119,4 +111,11 @@ public class OAuth2ProvidersRegistry { | ||||
|         return toDefault; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom | ||||
|      */ | ||||
|     private static class LazyHolder { | ||||
|         private static final OAuth2ProvidersRegistry INSTANCE = new OAuth2ProvidersRegistry(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -31,7 +31,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| 
 | ||||
| public class OAuth2QueryParser { | ||||
| 
 | ||||
|     private static final String TAG = OAuth2QueryParser.class.getName(); | ||||
|  | ||||
| @ -1,59 +1,52 @@ | ||||
| /** | ||||
|  *   ownCloud Android client application | ||||
|  * | ||||
|  *   @author David González Verdugo | ||||
|  *   @author Christian Schabesberger | ||||
|  * | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  * | ||||
|  *   This program is free software: you can redistribute it and/or modify | ||||
|  *   it under the terms of the GNU General Public License version 2, | ||||
|  *   as published by the Free Software Foundation. | ||||
|  * | ||||
|  *   This program is distributed in the hope that it will be useful, | ||||
|  *   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *   GNU General Public License for more details. | ||||
|  * | ||||
|  *   You should have received a copy of the GNU General Public License | ||||
|  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * ownCloud Android client application | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  * @author Christian Schabesberger | ||||
|  * <p> | ||||
|  * Copyright (C) 2018 ownCloud GmbH. | ||||
|  * <p> | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2, | ||||
|  * as published by the Free Software Foundation. | ||||
|  * <p> | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * <p> | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials; | ||||
| import com.owncloud.android.lib.common.authentication.OwnCloudCredentials; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| 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 okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| 
 | ||||
| import okhttp3.MultipartBody; | ||||
| import okhttp3.RequestBody; | ||||
| 
 | ||||
| public class OAuth2RefreshAccessTokenOperation extends RemoteOperation<Map<String, String>> { | ||||
| 
 | ||||
|     private static final String TAG = OAuth2RefreshAccessTokenOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     private final String mAccessTokenEndpointPath; | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
|     private String mClientId; | ||||
|     private String mClientSecret; | ||||
|     private String mRefreshToken; | ||||
| 
 | ||||
|     private final String mAccessTokenEndpointPath; | ||||
| 
 | ||||
|     private final OAuth2ResponseParser mResponseParser; | ||||
| 
 | ||||
|     public OAuth2RefreshAccessTokenOperation( | ||||
|             String clientId, | ||||
|             String secretId, | ||||
|  | ||||
| @ -30,10 +30,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation; | ||||
| 
 | ||||
| public interface OAuth2RequestBuilder { | ||||
| 
 | ||||
|     enum OAuthRequest { | ||||
|         GET_AUTHORIZATION_CODE, CREATE_ACCESS_TOKEN, REFRESH_ACCESS_TOKEN | ||||
|     } | ||||
| 
 | ||||
|     void setRequest(OAuthRequest operation); | ||||
| 
 | ||||
|     void setGrantType(OAuth2GrantType grantType); | ||||
| @ -45,4 +41,8 @@ public interface OAuth2RequestBuilder { | ||||
|     RemoteOperation buildOperation(); | ||||
| 
 | ||||
|     String buildUri(); | ||||
| 
 | ||||
|     enum OAuthRequest { | ||||
|         GET_AUTHORIZATION_CODE, CREATE_ACCESS_TOKEN, REFRESH_ACCESS_TOKEN | ||||
|     } | ||||
| } | ||||
| @ -1,27 +1,25 @@ | ||||
| /** | ||||
|  *   ownCloud Android client application | ||||
|  * | ||||
|  *   @author David A. Velasco | ||||
|  * | ||||
|  *   Copyright (C) 2017 ownCloud GmbH. | ||||
|  * | ||||
|  *   This program is free software: you can redistribute it and/or modify | ||||
|  *   it under the terms of the GNU General Public License version 2, | ||||
|  *   as published by the Free Software Foundation. | ||||
|  * | ||||
|  *   This program is distributed in the hope that it will be useful, | ||||
|  *   but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  *   GNU General Public License for more details. | ||||
|  * | ||||
|  *   You should have received a copy of the GNU General Public License | ||||
|  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  * ownCloud Android client application | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  * <p> | ||||
|  * Copyright (C) 2017 ownCloud GmbH. | ||||
|  * <p> | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2, | ||||
|  * as published by the Free Software Foundation. | ||||
|  * <p> | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * <p> | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.authentication.oauth; | ||||
| 
 | ||||
| 
 | ||||
| import org.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| @ -35,40 +33,40 @@ class OAuth2ResponseParser { | ||||
| 
 | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_ACCESS_TOKEN)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_ACCESS_TOKEN, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_ACCESS_TOKEN)); | ||||
|                     getString(OAuth2Constants.KEY_ACCESS_TOKEN)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_TOKEN_TYPE)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_TOKEN_TYPE, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_TOKEN_TYPE)); | ||||
|                     getString(OAuth2Constants.KEY_TOKEN_TYPE)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_EXPIRES_IN)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_EXPIRES_IN, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_EXPIRES_IN)); | ||||
|                     getString(OAuth2Constants.KEY_EXPIRES_IN)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_REFRESH_TOKEN)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_REFRESH_TOKEN, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_REFRESH_TOKEN)); | ||||
|                     getString(OAuth2Constants.KEY_REFRESH_TOKEN)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_SCOPE)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_SCOPE, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_SCOPE)); | ||||
|                     getString(OAuth2Constants.KEY_SCOPE)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_ERROR)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_ERROR, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_ERROR)); | ||||
|                     getString(OAuth2Constants.KEY_ERROR)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_ERROR_DESCRIPTION)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_ERROR_DESCRIPTION, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_ERROR_DESCRIPTION)); | ||||
|                     getString(OAuth2Constants.KEY_ERROR_DESCRIPTION)); | ||||
|         } | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_ERROR_URI)) { | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_ERROR_URI, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_ERROR_URI)); | ||||
|                     getString(OAuth2Constants.KEY_ERROR_URI)); | ||||
|         } | ||||
| 
 | ||||
|         if (tokenJson.has(OAuth2Constants.KEY_USER_ID)) {   // not standard | ||||
|             resultTokenMap.put(OAuth2Constants.KEY_USER_ID, tokenJson. | ||||
|                 getString(OAuth2Constants.KEY_USER_ID)); | ||||
|                     getString(OAuth2Constants.KEY_USER_ID)); | ||||
|         } | ||||
| 
 | ||||
|         return resultTokenMap; | ||||
|  | ||||
| @ -46,19 +46,14 @@ public class OwnCloudOAuth2Provider implements OAuth2Provider { | ||||
|         return new OwnCloudOAuth2RequestBuilder(this); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration) { | ||||
|         mClientConfiguration = oAuth2ClientConfiguration; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public OAuth2ClientConfiguration getClientConfiguration() { | ||||
|         return mClientConfiguration; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setAuthorizationServerUri(String authorizationServerUri) { | ||||
|         mAuthorizationServerUrl = authorizationServerUri; | ||||
|     public void setClientConfiguration(OAuth2ClientConfiguration oAuth2ClientConfiguration) { | ||||
|         mClientConfiguration = oAuth2ClientConfiguration; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -66,6 +61,11 @@ public class OwnCloudOAuth2Provider implements OAuth2Provider { | ||||
|         return mAuthorizationServerUrl; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setAuthorizationServerUri(String authorizationServerUri) { | ||||
|         mAuthorizationServerUrl = authorizationServerUri; | ||||
|     } | ||||
| 
 | ||||
|     public String getAccessTokenEndpointPath() { | ||||
|         return mAccessTokenEndpointPath; | ||||
|     } | ||||
|  | ||||
| @ -68,22 +68,22 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
|         if (mGrantType != OAuth2GrantType.AUTHORIZATION_CODE && | ||||
|                 mGrantType != OAuth2GrantType.REFRESH_TOKEN) { | ||||
|             throw new UnsupportedOperationException( | ||||
|                 "Unsupported grant type. Only " + | ||||
|                     OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " and " + | ||||
|                         OAuth2GrantType.REFRESH_TOKEN + " are supported" | ||||
|                     "Unsupported grant type. Only " + | ||||
|                             OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " and " + | ||||
|                             OAuth2GrantType.REFRESH_TOKEN + " are supported" | ||||
|             ); | ||||
|         } | ||||
|         OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration(); | ||||
| 
 | ||||
|         switch(mRequest) { | ||||
|         switch (mRequest) { | ||||
|             case CREATE_ACCESS_TOKEN: | ||||
|                 return new OAuth2GetAccessTokenOperation( | ||||
|                     mGrantType.getValue(), | ||||
|                     mCode, | ||||
|                     clientConfiguration.getClientId(), | ||||
|                     clientConfiguration.getClientSecret(), | ||||
|                     clientConfiguration.getRedirectUri(), | ||||
|                     mOAuth2Provider.getAccessTokenEndpointPath() | ||||
|                         mGrantType.getValue(), | ||||
|                         mCode, | ||||
|                         clientConfiguration.getClientId(), | ||||
|                         clientConfiguration.getClientSecret(), | ||||
|                         clientConfiguration.getRedirectUri(), | ||||
|                         mOAuth2Provider.getAccessTokenEndpointPath() | ||||
|                 ); | ||||
| 
 | ||||
|             case REFRESH_ACCESS_TOKEN: | ||||
| @ -95,7 +95,7 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
|                 ); | ||||
|             default: | ||||
|                 throw new UnsupportedOperationException( | ||||
|                     "Unsupported request" | ||||
|                         "Unsupported request" | ||||
|                 ); | ||||
|         } | ||||
|     } | ||||
| @ -104,26 +104,26 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
|     public String buildUri() { | ||||
|         if (OAuth2GrantType.AUTHORIZATION_CODE != mGrantType) { | ||||
|             throw new UnsupportedOperationException( | ||||
|                 "Unsupported grant type. Only " + | ||||
|                     OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " is supported by this provider" | ||||
|                     "Unsupported grant type. Only " + | ||||
|                             OAuth2GrantType.AUTHORIZATION_CODE.getValue() + " is supported by this provider" | ||||
|             ); | ||||
|         } | ||||
|         OAuth2ClientConfiguration clientConfiguration = mOAuth2Provider.getClientConfiguration(); | ||||
|         Uri uri; | ||||
|         Uri.Builder uriBuilder; | ||||
|         switch(mRequest) { | ||||
|         switch (mRequest) { | ||||
|             case GET_AUTHORIZATION_CODE: | ||||
|                 uri = Uri.parse(mOAuth2Provider.getAuthorizationServerUri()); | ||||
|                 uriBuilder = uri.buildUpon(); | ||||
|                 uriBuilder.appendEncodedPath(mOAuth2Provider.getAuthorizationCodeEndpointPath()); | ||||
|                 uriBuilder.appendQueryParameter( | ||||
|                     OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE | ||||
|                         OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE | ||||
|                 ); | ||||
|                 uriBuilder.appendQueryParameter( | ||||
|                     OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri() | ||||
|                         OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri() | ||||
|                 ); | ||||
|                 uriBuilder.appendQueryParameter( | ||||
|                     OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId() | ||||
|                         OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId() | ||||
|                 ); | ||||
| 
 | ||||
|                 uri = uriBuilder.build(); | ||||
| @ -134,13 +134,13 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
|                 uriBuilder = uri.buildUpon(); | ||||
|                 uriBuilder.appendEncodedPath(mOAuth2Provider.getAccessTokenEndpointPath()); | ||||
|                 uriBuilder.appendQueryParameter( | ||||
|                     OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE | ||||
|                         OAuth2Constants.KEY_RESPONSE_TYPE, OAuth2Constants.OAUTH2_RESPONSE_TYPE_CODE | ||||
|                 ); | ||||
|                 uriBuilder.appendQueryParameter( | ||||
|                     OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri() | ||||
|                         OAuth2Constants.KEY_REDIRECT_URI, clientConfiguration.getRedirectUri() | ||||
|                 ); | ||||
|                 uriBuilder.appendQueryParameter( | ||||
|                     OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId() | ||||
|                         OAuth2Constants.KEY_CLIENT_ID, clientConfiguration.getClientId() | ||||
|                 ); | ||||
| 
 | ||||
|                 uri = uriBuilder.build(); | ||||
| @ -148,7 +148,7 @@ public class OwnCloudOAuth2RequestBuilder implements OAuth2RequestBuilder { | ||||
| 
 | ||||
|             default: | ||||
|                 throw new UnsupportedOperationException( | ||||
|                     "Unsupported request" | ||||
|                         "Unsupported request" | ||||
|                 ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -32,7 +32,15 @@ import com.owncloud.android.lib.common.http.interceptors.RequestHeaderIntercepto | ||||
| import com.owncloud.android.lib.common.network.AdvancedX509TrustManager; | ||||
| import com.owncloud.android.lib.common.network.NetworkUtils; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.CookieJar; | ||||
| import okhttp3.HttpUrl; | ||||
| import okhttp3.OkHttpClient; | ||||
| import okhttp3.Protocol; | ||||
| 
 | ||||
| import javax.net.ssl.SSLContext; | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| @ -41,18 +49,9 @@ import java.util.List; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import javax.net.ssl.SSLContext; | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| 
 | ||||
| import okhttp3.Cookie; | ||||
| import okhttp3.CookieJar; | ||||
| import okhttp3.HttpUrl; | ||||
| import okhttp3.OkHttpClient; | ||||
| import okhttp3.Protocol; | ||||
| 
 | ||||
| /** | ||||
|  * Client used to perform network operations | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class HttpClient { | ||||
| @ -63,21 +62,13 @@ public class HttpClient { | ||||
|     private static Context sContext; | ||||
|     private static HashMap<String, List<Cookie>> sCookieStore = new HashMap<>(); | ||||
| 
 | ||||
|     public static void setContext(Context context) { | ||||
|         sContext = context; | ||||
|     } | ||||
| 
 | ||||
|     public Context getContext() { | ||||
|         return sContext; | ||||
|     } | ||||
| 
 | ||||
|     public static OkHttpClient getOkHttpClient() { | ||||
|         if (sOkHttpClient == null) { | ||||
|             try { | ||||
|                 final X509TrustManager trustManager = new AdvancedX509TrustManager( | ||||
|                         NetworkUtils.getKnownServersStore(sContext)); | ||||
|                 final SSLContext sslContext = SSLContext.getInstance("TLS"); | ||||
|                 sslContext.init(null, new TrustManager[] {trustManager}, null); | ||||
|                 sslContext.init(null, new TrustManager[]{trustManager}, null); | ||||
| 
 | ||||
|                 // Automatic cookie handling, NOT PERSISTENT | ||||
|                 CookieJar cookieJar = new CookieJar() { | ||||
| @ -109,8 +100,8 @@ public class HttpClient { | ||||
|                         .sslSocketFactory(sslContext.getSocketFactory(), trustManager) | ||||
|                         .hostnameVerifier((asdf, usdf) -> true) | ||||
|                         .cookieJar(cookieJar); | ||||
|                         // TODO: Not verifying the hostname against certificate. ask owncloud security human if this is ok. | ||||
|                         //.hostnameVerifier(new BrowserCompatHostnameVerifier()); | ||||
|                 // TODO: Not verifying the hostname against certificate. ask owncloud security human if this is ok. | ||||
|                 //.hostnameVerifier(new BrowserCompatHostnameVerifier()); | ||||
|                 sOkHttpClient = clientBuilder.build(); | ||||
| 
 | ||||
|             } catch (Exception e) { | ||||
| @ -130,6 +121,31 @@ public class HttpClient { | ||||
|         return sOkHttpInterceptor; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Add header that will be included for all the requests from now on | ||||
|      * | ||||
|      * @param headerName | ||||
|      * @param headerValue | ||||
|      */ | ||||
|     public static void addHeaderForAllRequests(String headerName, String headerValue) { | ||||
|         getOkHttpInterceptor() | ||||
|                 .addRequestInterceptor( | ||||
|                         new RequestHeaderInterceptor(headerName, headerValue) | ||||
|                 ); | ||||
|     } | ||||
| 
 | ||||
|     public static void deleteHeaderForAllRequests(String headerName) { | ||||
|         getOkHttpInterceptor().deleteRequestHeaderInterceptor(headerName); | ||||
|     } | ||||
| 
 | ||||
|     public Context getContext() { | ||||
|         return sContext; | ||||
|     } | ||||
| 
 | ||||
|     public static void setContext(Context context) { | ||||
|         sContext = context; | ||||
|     } | ||||
| 
 | ||||
|     public void disableAutomaticCookiesHandling() { | ||||
|         OkHttpClient.Builder clientBuilder = getOkHttpClient().newBuilder(); | ||||
|         clientBuilder.cookieJar(new CookieJar() { | ||||
| @ -146,22 +162,6 @@ public class HttpClient { | ||||
|         sOkHttpClient = clientBuilder.build(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Add header that will be included for all the requests from now on | ||||
|      * @param headerName | ||||
|      * @param headerValue | ||||
|      */ | ||||
|     public static void addHeaderForAllRequests(String headerName, String headerValue) { | ||||
|         getOkHttpInterceptor() | ||||
|                 .addRequestInterceptor( | ||||
|                         new RequestHeaderInterceptor(headerName, headerValue) | ||||
|                 ); | ||||
|     } | ||||
| 
 | ||||
|     public static void deleteHeaderForAllRequests(String headerName) { | ||||
|         getOkHttpInterceptor().deleteRequestHeaderInterceptor(headerName); | ||||
|     } | ||||
| 
 | ||||
|     public List<Cookie> getCookiesFromUrl(HttpUrl httpUrl) { | ||||
|         return sCookieStore.get(httpUrl.host()); | ||||
|     } | ||||
|  | ||||
| @ -181,9 +181,13 @@ public class HttpConstants { | ||||
|      *************************************************** TIMEOUTS ********************************************** | ||||
|      ***********************************************************************************************************/ | ||||
| 
 | ||||
|     /** Default timeout for waiting data from the server */ | ||||
|     /** | ||||
|      * Default timeout for waiting data from the server | ||||
|      */ | ||||
|     public static final int DEFAULT_DATA_TIMEOUT = 60000; | ||||
| 
 | ||||
|     /** Default timeout for establishing a connection */ | ||||
|     /** | ||||
|      * Default timeout for establishing a connection | ||||
|      */ | ||||
|     public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; | ||||
| } | ||||
| @ -24,16 +24,17 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.interceptors; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Iterator; | ||||
| 
 | ||||
| import okhttp3.Interceptor; | ||||
| import okhttp3.Request; | ||||
| import okhttp3.Response; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Iterator; | ||||
| 
 | ||||
| /** | ||||
|  * Http interceptor to use multiple interceptors in the same {@link okhttp3.OkHttpClient} instance | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class HttpInterceptor implements Interceptor { | ||||
| @ -58,20 +59,12 @@ public class HttpInterceptor implements Interceptor { | ||||
|         return response; | ||||
|     } | ||||
| 
 | ||||
|     public interface RequestInterceptor { | ||||
|         Request intercept(Request request) throws IOException; | ||||
|     } | ||||
| 
 | ||||
|     public interface ResponseInterceptor { | ||||
|         Response intercept(Response response) throws IOException; | ||||
|     } | ||||
| 
 | ||||
|     public HttpInterceptor addRequestInterceptor(RequestInterceptor requestInterceptor) { | ||||
|         mRequestInterceptors.add(requestInterceptor); | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     public HttpInterceptor addResponseInterceptor (ResponseInterceptor responseInterceptor) { | ||||
|     public HttpInterceptor addResponseInterceptor(ResponseInterceptor responseInterceptor) { | ||||
|         mResponseInterceptors.add(responseInterceptor); | ||||
|         return this; | ||||
|     } | ||||
| @ -106,4 +99,12 @@ public class HttpInterceptor implements Interceptor { | ||||
|     public ArrayList<ResponseInterceptor> getResponseInterceptors() { | ||||
|         return mResponseInterceptors; | ||||
|     } | ||||
| 
 | ||||
|     public interface RequestInterceptor { | ||||
|         Request intercept(Request request) throws IOException; | ||||
|     } | ||||
| 
 | ||||
|     public interface ResponseInterceptor { | ||||
|         Response intercept(Response response) throws IOException; | ||||
|     } | ||||
| } | ||||
| @ -25,12 +25,6 @@ | ||||
| package com.owncloud.android.lib.common.http.methods; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpClient; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import okhttp3.Call; | ||||
| import okhttp3.Headers; | ||||
| import okhttp3.HttpUrl; | ||||
| @ -39,6 +33,11 @@ import okhttp3.Request; | ||||
| import okhttp3.RequestBody; | ||||
| import okhttp3.Response; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Wrapper to perform http calls transparently by using: | ||||
|  * - OkHttp for non webdav methods | ||||
| @ -136,6 +135,12 @@ public abstract class HttpBaseMethod { | ||||
| 
 | ||||
|     // Connection parameters | ||||
| 
 | ||||
|     public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) { | ||||
|         mOkHttpClient = mOkHttpClient.newBuilder() | ||||
|                 .retryOnConnectionFailure(retryOnConnectionFailure) | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     public void setReadTimeout(long readTimeout, TimeUnit timeUnit) { | ||||
|         mOkHttpClient = mOkHttpClient.newBuilder() | ||||
|                 .readTimeout(readTimeout, timeUnit) | ||||
| @ -154,12 +159,6 @@ public abstract class HttpBaseMethod { | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) { | ||||
|         mOkHttpClient = mOkHttpClient.newBuilder() | ||||
|                 .retryOnConnectionFailure(retryOnConnectionFailure) | ||||
|                 .build(); | ||||
|     } | ||||
| 
 | ||||
|     // Request | ||||
| 
 | ||||
|     public void addRequestHeader(String name, String value) { | ||||
|  | ||||
| @ -27,13 +27,12 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * OkHttp delete calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class DeleteMethod extends HttpMethod{ | ||||
| public class DeleteMethod extends HttpMethod { | ||||
| 
 | ||||
|     public DeleteMethod(URL url) { | ||||
|         super(url); | ||||
|  | ||||
| @ -27,10 +27,9 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * OkHttp get calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class GetMethod extends HttpMethod { | ||||
|  | ||||
| @ -29,9 +29,6 @@ import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.Call; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * Wrapper to perform OkHttp calls | ||||
|  * | ||||
|  | ||||
| @ -27,15 +27,14 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| /** | ||||
|  * OkHttp post calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class PostMethod extends HttpMethod { | ||||
| 
 | ||||
|     public PostMethod(URL url){ | ||||
|     public PostMethod(URL url) { | ||||
|         super(url); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -27,11 +27,9 @@ package com.owncloud.android.lib.common.http.methods.nonwebdav; | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import okhttp3.HttpUrl; | ||||
| public class PutMethod extends HttpMethod { | ||||
| 
 | ||||
| public class PutMethod extends HttpMethod{ | ||||
| 
 | ||||
|     public PutMethod(URL url){ | ||||
|     public PutMethod(URL url) { | ||||
|         super(url); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -24,12 +24,13 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| /** | ||||
|  * Copy calls wrapper | ||||
|  * | ||||
|  * @author Christian Schabesberger | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
|  | ||||
| @ -24,23 +24,23 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Constants; | ||||
| import at.bitfire.dav4android.DavOCResource; | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import at.bitfire.dav4android.exception.RedirectException; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import okhttp3.HttpUrl; | ||||
| import okhttp3.Protocol; | ||||
| import okhttp3.Response; | ||||
| import okhttp3.ResponseBody; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Wrapper to perform WebDAV (dav4android) calls | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public abstract class DavMethod extends HttpBaseMethod { | ||||
| @ -124,6 +124,24 @@ public abstract class DavMethod extends HttpBaseMethod { | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setUrl(HttpUrl url) { | ||||
|         super.setUrl(url); | ||||
|         mDavResource = new DavOCResource( | ||||
|                 mOkHttpClient, | ||||
|                 HttpUrl.parse(mRequest.url().toString()), | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean getRetryOnConnectionFailure() { | ||||
|         return false; //TODO: implement me | ||||
|     } | ||||
| 
 | ||||
|     ////////////////////////////// | ||||
|     //         Getter | ||||
|     ////////////////////////////// | ||||
| 
 | ||||
|     @Override | ||||
|     public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) { | ||||
|         super.setRetryOnConnectionFailure(retryOnConnectionFailure); | ||||
| @ -133,24 +151,6 @@ public abstract class DavMethod extends HttpBaseMethod { | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void setUrl(HttpUrl url){ | ||||
|         super.setUrl(url); | ||||
|         mDavResource = new DavOCResource( | ||||
|                 mOkHttpClient, | ||||
|                 HttpUrl.parse(mRequest.url().toString()), | ||||
|                 Constants.INSTANCE.getLog()); | ||||
|     } | ||||
| 
 | ||||
|     ////////////////////////////// | ||||
|     //         Getter | ||||
|     ////////////////////////////// | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean getRetryOnConnectionFailure() { | ||||
|         return false; //TODO: implement me | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean isAborted() { | ||||
|         return mDavResource.isCallAborted(); | ||||
|  | ||||
| @ -24,12 +24,13 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| /** | ||||
|  * MkCol calls wrapper | ||||
|  * | ||||
|  * @author Christian Schabesberger | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
|  | ||||
| @ -25,13 +25,13 @@ | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| /** | ||||
|  * Move calls wrapper | ||||
|  * | ||||
|  * @author Christian Schabesberger | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
|  | ||||
| @ -24,18 +24,19 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.Response; | ||||
| import at.bitfire.dav4android.exception.DavException; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| /** | ||||
|  * Propfind calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class PropfindMethod extends DavMethod { | ||||
| @ -57,7 +58,7 @@ public class PropfindMethod extends DavMethod { | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int onExecute() throws IOException, DavException{ | ||||
|     public int onExecute() throws IOException, DavException { | ||||
|         mDavResource.propfind(mDepth, mPropertiesToRequest, | ||||
|                 (Response response, Response.HrefRelation hrefRelation) -> { | ||||
|                     switch (hrefRelation) { | ||||
|  | ||||
| @ -24,23 +24,25 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.http.methods.webdav; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.net.URL; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import kotlin.Unit; | ||||
| 
 | ||||
| /** | ||||
|  * Put calls wrapper | ||||
|  * | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| public class PutMethod extends DavMethod { | ||||
| 
 | ||||
|     public PutMethod(URL url) { | ||||
|         super(url); | ||||
|     }; | ||||
|     } | ||||
| 
 | ||||
|     ; | ||||
| 
 | ||||
|     @Override | ||||
|     public int onExecute() throws IOException, HttpException { | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,6 +24,11 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.TrustManagerFactory; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| import java.security.KeyStore; | ||||
| import java.security.KeyStoreException; | ||||
| import java.security.NoSuchAlgorithmException; | ||||
| @ -34,19 +39,11 @@ import java.security.cert.CertificateExpiredException; | ||||
| import java.security.cert.CertificateNotYetValidException; | ||||
| import java.security.cert.X509Certificate; | ||||
| 
 | ||||
| import javax.net.ssl.TrustManager; | ||||
| import javax.net.ssl.TrustManagerFactory; | ||||
| import javax.net.ssl.X509TrustManager; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * @author David A. Velasco | ||||
|  */ | ||||
| public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|      | ||||
| 
 | ||||
|     private static final String TAG = AdvancedX509TrustManager.class.getSimpleName(); | ||||
| 
 | ||||
|     private X509TrustManager mStandardTrustManager = null; | ||||
| @ -54,27 +51,27 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor for AdvancedX509TrustManager | ||||
|      *  | ||||
|      * @param  knownServersKeyStore    Local certificates store with server certificates explicitly trusted by the user. | ||||
|      * @throws CertStoreException       When no default X509TrustManager instance was found in the system. | ||||
|      * | ||||
|      * @param knownServersKeyStore Local certificates store with server certificates explicitly trusted by the user. | ||||
|      * @throws CertStoreException When no default X509TrustManager instance was found in the system. | ||||
|      */ | ||||
|     public AdvancedX509TrustManager(KeyStore knownServersKeyStore) | ||||
|             throws NoSuchAlgorithmException, KeyStoreException, CertStoreException { | ||||
|         super(); | ||||
|         TrustManagerFactory factory = TrustManagerFactory | ||||
|                 .getInstance(TrustManagerFactory.getDefaultAlgorithm()); | ||||
|         factory.init((KeyStore)null); | ||||
|         factory.init((KeyStore) null); | ||||
|         mStandardTrustManager = findX509TrustManager(factory); | ||||
| 
 | ||||
|         mKnownServersKeyStore = knownServersKeyStore; | ||||
|     } | ||||
|      | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * Locates the first X509TrustManager provided by a given TrustManagerFactory | ||||
|      * @param factory               TrustManagerFactory to inspect in the search for a X509TrustManager | ||||
|      * @return                      The first X509TrustManager found in factory. | ||||
|      * @throws CertStoreException   When no X509TrustManager instance was found in factory | ||||
|      * | ||||
|      * @param factory TrustManagerFactory to inspect in the search for a X509TrustManager | ||||
|      * @return The first X509TrustManager found in factory. | ||||
|      * @throws CertStoreException When no X509TrustManager instance was found in factory | ||||
|      */ | ||||
|     private X509TrustManager findX509TrustManager(TrustManagerFactory factory) throws CertStoreException { | ||||
|         TrustManager tms[] = factory.getTrustManagers(); | ||||
| @ -85,36 +82,34 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[], | ||||
|      *      String authType) | ||||
|      * String authType) | ||||
|      */ | ||||
|     public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException { | ||||
|         mStandardTrustManager.checkClientTrusted(certificates, authType); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     /** | ||||
|      * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], | ||||
|      *      String authType) | ||||
|      * String authType) | ||||
|      */ | ||||
|     public void checkServerTrusted(X509Certificate[] certificates, String authType) { | ||||
|         if (!isKnownServer(certificates[0])) { | ||||
|         	CertificateCombinedException result = new CertificateCombinedException(certificates[0]); | ||||
|         	try { | ||||
|         		certificates[0].checkValidity(); | ||||
|         	} catch (CertificateExpiredException c) { | ||||
|         		result.setCertificateExpiredException(c); | ||||
|         		 | ||||
|         	} catch (CertificateNotYetValidException c) { | ||||
|             CertificateCombinedException result = new CertificateCombinedException(certificates[0]); | ||||
|             try { | ||||
|                 certificates[0].checkValidity(); | ||||
|             } catch (CertificateExpiredException c) { | ||||
|                 result.setCertificateExpiredException(c); | ||||
| 
 | ||||
|             } catch (CertificateNotYetValidException c) { | ||||
|                 result.setCertificateNotYetException(c); | ||||
|         	} | ||||
|         	 | ||||
|         	try { | ||||
|         	    mStandardTrustManager.checkServerTrusted(certificates, authType); | ||||
|         	} catch (CertificateException c) { | ||||
|             } | ||||
| 
 | ||||
|             try { | ||||
|                 mStandardTrustManager.checkServerTrusted(certificates, authType); | ||||
|             } catch (CertificateException c) { | ||||
|                 Throwable cause = c.getCause(); | ||||
|                 Throwable previousCause = null; | ||||
|                 while (cause != null && cause != previousCause && !(cause instanceof CertPathValidatorException)) {     // getCause() is not funny | ||||
| @ -122,19 +117,19 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|                     cause = cause.getCause(); | ||||
|                 } | ||||
|                 if (cause != null && cause instanceof CertPathValidatorException) { | ||||
|                 	result.setCertPathValidatorException((CertPathValidatorException)cause); | ||||
|                     result.setCertPathValidatorException((CertPathValidatorException) cause); | ||||
|                 } else { | ||||
|                 	result.setOtherCertificateException(c); | ||||
|                     result.setOtherCertificateException(c); | ||||
|                 } | ||||
|         	} | ||||
|         	 | ||||
|         	if (result.isException()) | ||||
|         		throw result; | ||||
|             } | ||||
| 
 | ||||
|             if (result.isException()) { | ||||
|                 throw result; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
|      | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() | ||||
|      */ | ||||
| @ -142,7 +137,6 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|         return mStandardTrustManager.getAcceptedIssuers(); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     public boolean isKnownServer(X509Certificate cert) { | ||||
|         try { | ||||
|             return (mKnownServersKeyStore.getCertificateAlias(cert) != null); | ||||
| @ -151,5 +145,5 @@ public class AdvancedX509TrustManager implements X509TrustManager { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
| } | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,36 +24,37 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| import java.security.cert.CertPathValidatorException; | ||||
| import java.security.cert.CertificateException; | ||||
| import java.security.cert.CertificateExpiredException; | ||||
| import java.security.cert.CertificateNotYetValidException; | ||||
| import java.security.cert.X509Certificate; | ||||
| 
 | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| 
 | ||||
| /** | ||||
|  * Exception joining all the problems that {@link AdvancedX509TrustManager} can find in | ||||
|  * a certificate chain for a server. | ||||
|  *  | ||||
|  * <p> | ||||
|  * This was initially created as an extension of CertificateException, but some | ||||
|  * implementations of the SSL socket layer in existing devices are REPLACING the CertificateException | ||||
|  * instances thrown by {@link javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], String)} | ||||
|  * with SSLPeerUnverifiedException FORGETTING THE CAUSING EXCEPTION instead of wrapping it.  | ||||
|  *  | ||||
|  * Due to this, extending RuntimeException is necessary to get that the CertificateCombinedException  | ||||
|  * with SSLPeerUnverifiedException FORGETTING THE CAUSING EXCEPTION instead of wrapping it. | ||||
|  * <p> | ||||
|  * Due to this, extending RuntimeException is necessary to get that the CertificateCombinedException | ||||
|  * instance reaches {@link AdvancedSslSocketFactory#verifyPeerIdentity}. | ||||
|  *  | ||||
|  * <p> | ||||
|  * BE CAREFUL. As a RuntimeException extensions, Java compilers do not require to handle it | ||||
|  * in client methods. Be sure to use it only when you know exactly where it will go. | ||||
|  *  | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  */ | ||||
| public class CertificateCombinedException extends RuntimeException { | ||||
| 
 | ||||
|     /** Generated - to refresh every time the class changes */ | ||||
|     /** | ||||
|      * Generated - to refresh every time the class changes | ||||
|      */ | ||||
|     private static final long serialVersionUID = -8875782030758554999L; | ||||
|      | ||||
| 
 | ||||
|     private X509Certificate mServerCert = null; | ||||
|     private String mHostInUrl; | ||||
| 
 | ||||
| @ -62,7 +63,7 @@ public class CertificateCombinedException extends RuntimeException { | ||||
|     private CertPathValidatorException mCertPathValidatorException = null; | ||||
|     private CertificateException mOtherCertificateException = null; | ||||
|     private SSLPeerUnverifiedException mSslPeerUnverifiedException = null; | ||||
|      | ||||
| 
 | ||||
|     public CertificateCombinedException(X509Certificate x509Certificate) { | ||||
|         mServerCert = x509Certificate; | ||||
|     } | ||||
| @ -84,7 +85,7 @@ public class CertificateCombinedException extends RuntimeException { | ||||
|     } | ||||
| 
 | ||||
|     public void setCertificateExpiredException(CertificateExpiredException c) { | ||||
|         mCertificateExpiredException  = c; | ||||
|         mCertificateExpiredException = c; | ||||
|     } | ||||
| 
 | ||||
|     public CertificateNotYetValidException getCertificateNotYetValidException() { | ||||
| @ -112,7 +113,7 @@ public class CertificateCombinedException extends RuntimeException { | ||||
|     } | ||||
| 
 | ||||
|     public SSLPeerUnverifiedException getSslPeerUnverifiedException() { | ||||
|         return mSslPeerUnverifiedException ;  | ||||
|         return mSslPeerUnverifiedException; | ||||
|     } | ||||
| 
 | ||||
|     public void setSslPeerUnverifiedException(SSLPeerUnverifiedException s) { | ||||
|  | ||||
| @ -27,6 +27,8 @@ package com.owncloud.android.lib.common.network; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.MediaType; | ||||
| import okio.BufferedSink; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| @ -34,9 +36,6 @@ import java.nio.ByteBuffer; | ||||
| import java.nio.channels.FileChannel; | ||||
| import java.util.Iterator; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| import okio.BufferedSink; | ||||
| 
 | ||||
| /** | ||||
|  * A Request body that represents a file chunk and include information about the progress when uploading it | ||||
|  * | ||||
| @ -84,18 +83,19 @@ public class ChunkFromFileRequestBody extends FileRequestBody { | ||||
|         try { | ||||
|             mChannel.position(mOffset); | ||||
|             long size = mFile.length(); | ||||
|             if (size == 0) size = -1; | ||||
|             if (size == 0) { | ||||
|                 size = -1; | ||||
|             } | ||||
|             long maxCount = Math.min(mOffset + mChunkSize, mChannel.size()); | ||||
|             while (mChannel.position() < maxCount) { | ||||
| 
 | ||||
| 
 | ||||
|                 Log_OC.d(TAG, "Sink buffer size: " + sink.buffer().size()); | ||||
| 
 | ||||
|                 readCount = mChannel.read(mBuffer); | ||||
| 
 | ||||
|                 Log_OC.d(TAG, "Read " + readCount + " bytes from file channel to " + mBuffer.toString()); | ||||
| 
 | ||||
|                 sink.buffer().write(mBuffer.array(), 0 ,readCount); | ||||
|                 sink.buffer().write(mBuffer.array(), 0, readCount); | ||||
| 
 | ||||
|                 sink.flush(); | ||||
| 
 | ||||
| @ -118,14 +118,14 @@ public class ChunkFromFileRequestBody extends FileRequestBody { | ||||
|         } catch (Exception exception) { | ||||
| 
 | ||||
|             Log.e(TAG, exception.toString()); | ||||
| //            // any read problem will be handled as if the file is not there | ||||
| //            if (io instanceof FileNotFoundException) { | ||||
| //                throw io; | ||||
| //            } else { | ||||
| //                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file"); | ||||
| //                fnf.initCause(io); | ||||
| //                throw fnf; | ||||
| //            } | ||||
|             //            // any read problem will be handled as if the file is not there | ||||
|             //            if (io instanceof FileNotFoundException) { | ||||
|             //                throw io; | ||||
|             //            } else { | ||||
|             //                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file"); | ||||
|             //                fnf.initCause(io); | ||||
|             //                throw fnf; | ||||
|             //            } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -26,7 +26,11 @@ package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.MediaType; | ||||
| import okhttp3.RequestBody; | ||||
| import okio.BufferedSink; | ||||
| import okio.Okio; | ||||
| import okio.Source; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.Collection; | ||||
| @ -34,12 +38,6 @@ import java.util.HashSet; | ||||
| import java.util.Iterator; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| import okhttp3.RequestBody; | ||||
| import okio.BufferedSink; | ||||
| import okio.Okio; | ||||
| import okio.Source; | ||||
| 
 | ||||
| /** | ||||
|  * A Request body that represents a file and include information about the progress when uploading it | ||||
|  * | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,6 +24,11 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import org.apache.http.conn.ssl.X509HostnameVerifier; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileOutputStream; | ||||
| @ -35,54 +40,50 @@ import java.security.NoSuchAlgorithmException; | ||||
| import java.security.cert.Certificate; | ||||
| import java.security.cert.CertificateException; | ||||
| 
 | ||||
| 
 | ||||
| import org.apache.http.conn.ssl.X509HostnameVerifier; | ||||
| 
 | ||||
| import android.content.Context; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| public class NetworkUtils { | ||||
|      | ||||
|     final private static String TAG = NetworkUtils.class.getSimpleName(); | ||||
|      | ||||
|     /** Default timeout for waiting data from the server */ | ||||
|     public static final int DEFAULT_DATA_TIMEOUT = 60000; | ||||
|      | ||||
|     /** Default timeout for establishing a connection */ | ||||
|     public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; | ||||
|      | ||||
|     /** Standard name for protocol TLS version 1.2 in Java Secure Socket Extension (JSSE) API */ | ||||
|     public static final String PROTOCOL_TLSv1_2 = "TLSv1.2"; | ||||
|      | ||||
|     /** Standard name for protocol TLS version 1.0 in JSSE API */ | ||||
|     public static final String PROTOCOL_TLSv1_0 = "TLSv1"; | ||||
| 
 | ||||
|     /** | ||||
|      * Default timeout for waiting data from the server | ||||
|      */ | ||||
|     public static final int DEFAULT_DATA_TIMEOUT = 60000; | ||||
|     /** | ||||
|      * Default timeout for establishing a connection | ||||
|      */ | ||||
|     public static final int DEFAULT_CONNECTION_TIMEOUT = 60000; | ||||
|     /** | ||||
|      * Standard name for protocol TLS version 1.2 in Java Secure Socket Extension (JSSE) API | ||||
|      */ | ||||
|     public static final String PROTOCOL_TLSv1_2 = "TLSv1.2"; | ||||
|     /** | ||||
|      * Standard name for protocol TLS version 1.0 in JSSE API | ||||
|      */ | ||||
|     public static final String PROTOCOL_TLSv1_0 = "TLSv1"; | ||||
|     final private static String TAG = NetworkUtils.class.getSimpleName(); | ||||
|     private static X509HostnameVerifier mHostnameVerifier = null; | ||||
| 
 | ||||
|     private static String LOCAL_TRUSTSTORE_FILENAME = "knownServers.bks"; | ||||
|      | ||||
| 
 | ||||
|     private static String LOCAL_TRUSTSTORE_PASSWORD = "password"; | ||||
| 
 | ||||
|     private static KeyStore mKnownServersStore = null; | ||||
|      | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the local store of reliable server certificates, explicitly accepted by the user. | ||||
|      *  | ||||
|      * <p> | ||||
|      * Returns a KeyStore instance with empty content if the local store was never created. | ||||
|      *  | ||||
|      * <p> | ||||
|      * Loads the store from the storage environment if needed. | ||||
|      *  | ||||
|      * @param context                       Android context where the operation is being performed. | ||||
|      * @return                              KeyStore instance with explicitly-accepted server certificates.  | ||||
|      * @throws KeyStoreException            When the KeyStore instance could not be created. | ||||
|      * @throws IOException                  When an existing local trust store could not be loaded. | ||||
|      * @throws NoSuchAlgorithmException     When the existing local trust store was saved with an unsupported algorithm. | ||||
|      * @throws CertificateException         When an exception occurred while loading the certificates from the local  | ||||
|      * 										trust store. | ||||
|      * | ||||
|      * @param context Android context where the operation is being performed. | ||||
|      * @return KeyStore instance with explicitly-accepted server certificates. | ||||
|      * @throws KeyStoreException        When the KeyStore instance could not be created. | ||||
|      * @throws IOException              When an existing local trust store could not be loaded. | ||||
|      * @throws NoSuchAlgorithmException When the existing local trust store was saved with an unsupported algorithm. | ||||
|      * @throws CertificateException     When an exception occurred while loading the certificates from the local | ||||
|      *                                  trust store. | ||||
|      */ | ||||
|     public static KeyStore getKnownServersStore(Context context) | ||||
|     		throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { | ||||
|             throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { | ||||
|         if (mKnownServersStore == null) { | ||||
|             //mKnownServersStore = KeyStore.getInstance("BKS"); | ||||
|             mKnownServersStore = KeyStore.getInstance(KeyStore.getDefaultType()); | ||||
| @ -96,17 +97,16 @@ public class NetworkUtils { | ||||
|                     in.close(); | ||||
|                 } | ||||
|             } else { | ||||
|             	// next is necessary to initialize an empty KeyStore instance | ||||
|             	mKnownServersStore.load(null, LOCAL_TRUSTSTORE_PASSWORD.toCharArray());  | ||||
|                 // next is necessary to initialize an empty KeyStore instance | ||||
|                 mKnownServersStore.load(null, LOCAL_TRUSTSTORE_PASSWORD.toCharArray()); | ||||
|             } | ||||
|         } | ||||
|         return mKnownServersStore; | ||||
|     } | ||||
|      | ||||
|      | ||||
|     public static void addCertToKnownServersStore(Certificate cert, Context context)  | ||||
|     		throws  KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { | ||||
|     	 | ||||
| 
 | ||||
|     public static void addCertToKnownServersStore(Certificate cert, Context context) | ||||
|             throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { | ||||
| 
 | ||||
|         KeyStore knownServers = getKnownServersStore(context); | ||||
|         knownServers.setCertificateEntry(Integer.toString(cert.hashCode()), cert); | ||||
|         FileOutputStream fos = null; | ||||
| @ -118,13 +118,13 @@ public class NetworkUtils { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isCertInKnownServersStore(Certificate cert, Context context)  | ||||
|     		throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { | ||||
|     	 | ||||
|     	KeyStore knownServers = getKnownServersStore(context); | ||||
|     	Log_OC.d(TAG, "Certificate - HashCode: " + cert.hashCode() + " " | ||||
|     			+ Boolean.toString(knownServers.isCertificateEntry(Integer.toString(cert.hashCode())))); | ||||
|     	return knownServers.isCertificateEntry(Integer.toString(cert.hashCode())); | ||||
|     public static boolean isCertInKnownServersStore(Certificate cert, Context context) | ||||
|             throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { | ||||
| 
 | ||||
|         KeyStore knownServers = getKnownServersStore(context); | ||||
|         Log_OC.d(TAG, "Certificate - HashCode: " + cert.hashCode() + " " | ||||
|                 + Boolean.toString(knownServers.isCertificateEntry(Integer.toString(cert.hashCode())))); | ||||
|         return knownServers.isCertificateEntry(Integer.toString(cert.hashCode())); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,23 +1,23 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *   Copyright (C) 2012  Bartek Przybylski | ||||
|  *    | ||||
|  * | ||||
|  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  *   of this software and associated documentation files (the "Software"), to deal | ||||
|  *   in the Software without restriction, including without limitation the rights | ||||
|  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  *   copies of the Software, and to permit persons to whom the Software is | ||||
|  *   furnished to do so, subject to the following conditions: | ||||
|  *    | ||||
|  * | ||||
|  *   The above copyright notice and this permission notice shall be included in | ||||
|  *   all copies or substantial portions of the Software. | ||||
|  *    | ||||
|  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -26,11 +26,10 @@ package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| 
 | ||||
| public interface ProgressiveDataTransferer { | ||||
| 
 | ||||
|     public void addDatatransferProgressListener (OnDatatransferProgressListener listener); | ||||
|      | ||||
|     public void addDatatransferProgressListener(OnDatatransferProgressListener listener); | ||||
| 
 | ||||
|     public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners); | ||||
| 
 | ||||
|     public void removeDatatransferProgressListener(OnDatatransferProgressListener listener); | ||||
|  | ||||
| @ -27,22 +27,19 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Aggregate saving the list of URLs followed in a sequence of redirections during the exceution of a | ||||
|  * {@link RemoteOperation}, and the status codes corresponding to all | ||||
|  * of them. | ||||
|  * | ||||
|  * <p> | ||||
|  * 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. | ||||
|  * | ||||
|  * <p> | ||||
|  * If no redirection was followed, the last (and first) status code contained corresponds to the original URL in the | ||||
|  * request. | ||||
|  */ | ||||
| @ -59,9 +56,9 @@ public class RedirectionPath { | ||||
|     /** | ||||
|      * 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 | ||||
|      * @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) { | ||||
| @ -75,7 +72,7 @@ public class RedirectionPath { | ||||
|     /** | ||||
|      * Adds a new location URL to the list of followed redirections. | ||||
|      * | ||||
|      * @param location      URL extracted from a 'Location' header in a redirection. | ||||
|      * @param location URL extracted from a 'Location' header in a redirection. | ||||
|      */ | ||||
|     public void addLocation(String location) { | ||||
|         if (mLocations == null) { | ||||
| @ -86,11 +83,10 @@ public class RedirectionPath { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 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. | ||||
|      * @param status Status code from the response of another followed redirection. | ||||
|      */ | ||||
|     public void addStatus(int status) { | ||||
|         if (mLastStatus < mStatuses.length - 1) { | ||||
| @ -99,14 +95,14 @@ public class RedirectionPath { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return      Last status code saved. | ||||
|      * @return Last status code saved. | ||||
|      */ | ||||
|     public int getLastStatus() { | ||||
|         return mStatuses[mLastStatus]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return      Last location followed corresponding to a permanent redirection (status code 301). | ||||
|      * @return Last location followed corresponding to a permanent redirection (status code 301). | ||||
|      */ | ||||
|     public String getLastPermanentLocation() { | ||||
|         for (int i = mLastStatus; i >= 0; i--) { | ||||
| @ -118,11 +114,10 @@ public class RedirectionPath { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return      Count of locations. | ||||
|      * @return Count of locations. | ||||
|      */ | ||||
|     public int getRedirectionsCount() { | ||||
|         return mLastLocation + 1; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,128 +24,122 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import javax.net.ssl.SSLSocket; | ||||
| import java.lang.ref.WeakReference; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
| 
 | ||||
| import javax.net.ssl.SSLSocket; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Enables the support of Server Name Indication if existing  | ||||
|  * Enables the support of Server Name Indication if existing | ||||
|  * in the underlying network implementation. | ||||
|  *  | ||||
|  * <p> | ||||
|  * Build as a singleton. | ||||
|  *  | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  */ | ||||
| public class ServerNameIndicator { | ||||
| 	 | ||||
| 	private static final String TAG = ServerNameIndicator.class.getSimpleName(); | ||||
| 	 | ||||
| 	private static final AtomicReference<ServerNameIndicator> mSingleInstance = new AtomicReference<ServerNameIndicator>(); | ||||
| 	 | ||||
| 	private static final String METHOD_NAME = "setHostname"; | ||||
| 	 | ||||
| 	private final WeakReference<Class<?>> mSSLSocketClassRef; | ||||
| 	private final WeakReference<Method> mSetHostnameMethodRef; | ||||
| 	 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Private constructor, class is a singleton. | ||||
| 	 *  | ||||
| 	 * @param sslSocketClass		Underlying implementation class of {@link SSLSocket} used to connect with the server.  | ||||
| 	 * @param setHostnameMethod		Name of the method to call to enable the SNI support. | ||||
| 	 */ | ||||
| 	private ServerNameIndicator(Class<?> sslSocketClass, Method setHostnameMethod) { | ||||
| 		mSSLSocketClassRef = new WeakReference<Class<?>>(sslSocketClass); | ||||
| 		mSetHostnameMethodRef = (setHostnameMethod == null) ? null : new WeakReference<Method>(setHostnameMethod); | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Calls the {@code #setHostname(String)} method of the underlying implementation  | ||||
| 	 * of {@link SSLSocket} if exists. | ||||
| 	 *  | ||||
| 	 * Creates and initializes the single instance of the class when needed | ||||
| 	 * | ||||
| 	 * @param hostname 		The name of the server host of interest. | ||||
| 	 * @param sslSocket 	Client socket to connect with the server. | ||||
| 	 */ | ||||
| 	public static void setServerNameIndication(String hostname, SSLSocket sslSocket) { | ||||
| 		final Method setHostnameMethod = getMethod(sslSocket); | ||||
| 		if (setHostnameMethod != null) { | ||||
| 			try { | ||||
| 				setHostnameMethod.invoke(sslSocket, hostname); | ||||
| 				Log_OC.i(TAG, "SNI done, hostname: " + hostname); | ||||
| 				 | ||||
| 			} catch (IllegalArgumentException e) { | ||||
| 				Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); | ||||
| 				 | ||||
| 			} catch (IllegalAccessException e) { | ||||
| 				Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); | ||||
| 				 | ||||
| 			} catch (InvocationTargetException e) { | ||||
| 				Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); | ||||
| 			} | ||||
| 		} else { | ||||
| 			Log_OC.i(TAG, "SNI not supported"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Gets the method to invoke trying to minimize the effective  | ||||
| 	 * application of reflection. | ||||
| 	 *  | ||||
| 	 * @param 	sslSocket		Instance of the SSL socket to use in connection with server. | ||||
| 	 * @return					Method to call to indicate the server name of interest to the server. | ||||
| 	 */ | ||||
| 	private static Method getMethod(SSLSocket sslSocket) { | ||||
| 		final Class<?> sslSocketClass = sslSocket.getClass(); | ||||
| 		final ServerNameIndicator instance = mSingleInstance.get(); | ||||
| 		if (instance == null) { | ||||
| 			return initFrom(sslSocketClass); | ||||
| 			 | ||||
| 		} else if (instance.mSSLSocketClassRef.get() != sslSocketClass) { | ||||
| 			// the underlying class changed | ||||
| 			return initFrom(sslSocketClass); | ||||
| 				 | ||||
| 		} else if (instance.mSetHostnameMethodRef == null) { | ||||
| 			// SNI not supported | ||||
| 			return null; | ||||
| 				 | ||||
| 		} else { | ||||
| 			final Method cachedSetHostnameMethod = instance.mSetHostnameMethodRef.get(); | ||||
| 			return (cachedSetHostnameMethod == null) ? initFrom(sslSocketClass) : cachedSetHostnameMethod; | ||||
| 		} | ||||
| 	} | ||||
|     private static final String TAG = ServerNameIndicator.class.getSimpleName(); | ||||
| 
 | ||||
|     private static final AtomicReference<ServerNameIndicator> mSingleInstance = new AtomicReference<ServerNameIndicator>(); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Singleton initializer. | ||||
| 	 *  | ||||
| 	 * Uses reflection to extract and 'cache' the method to invoke to indicate the desited host name to the server side. | ||||
| 	 *   | ||||
| 	 * @param 	sslSocketClass		Underlying class providing the implementation of {@link SSLSocket}. | ||||
| 	 * @return						Method to call to indicate the server name of interest to the server. | ||||
| 	 */ | ||||
| 	private static Method initFrom(Class<?> sslSocketClass) { | ||||
|     private static final String METHOD_NAME = "setHostname"; | ||||
| 
 | ||||
|     private final WeakReference<Class<?>> mSSLSocketClassRef; | ||||
|     private final WeakReference<Method> mSetHostnameMethodRef; | ||||
| 
 | ||||
|     /** | ||||
|      * Private constructor, class is a singleton. | ||||
|      * | ||||
|      * @param sslSocketClass    Underlying implementation class of {@link SSLSocket} used to connect with the server. | ||||
|      * @param setHostnameMethod Name of the method to call to enable the SNI support. | ||||
|      */ | ||||
|     private ServerNameIndicator(Class<?> sslSocketClass, Method setHostnameMethod) { | ||||
|         mSSLSocketClassRef = new WeakReference<Class<?>>(sslSocketClass); | ||||
|         mSetHostnameMethodRef = (setHostnameMethod == null) ? null : new WeakReference<Method>(setHostnameMethod); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Calls the {@code #setHostname(String)} method of the underlying implementation | ||||
|      * of {@link SSLSocket} if exists. | ||||
|      * <p> | ||||
|      * Creates and initializes the single instance of the class when needed | ||||
|      * | ||||
|      * @param hostname  The name of the server host of interest. | ||||
|      * @param sslSocket Client socket to connect with the server. | ||||
|      */ | ||||
|     public static void setServerNameIndication(String hostname, SSLSocket sslSocket) { | ||||
|         final Method setHostnameMethod = getMethod(sslSocket); | ||||
|         if (setHostnameMethod != null) { | ||||
|             try { | ||||
|                 setHostnameMethod.invoke(sslSocket, hostname); | ||||
|                 Log_OC.i(TAG, "SNI done, hostname: " + hostname); | ||||
| 
 | ||||
|             } catch (IllegalArgumentException e) { | ||||
|                 Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); | ||||
| 
 | ||||
|             } catch (IllegalAccessException e) { | ||||
|                 Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); | ||||
| 
 | ||||
|             } catch (InvocationTargetException e) { | ||||
|                 Log_OC.e(TAG, "Call to SSLSocket#setHost(String) failed ", e); | ||||
|             } | ||||
|         } else { | ||||
|             Log_OC.i(TAG, "SNI not supported"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the method to invoke trying to minimize the effective | ||||
|      * application of reflection. | ||||
|      * | ||||
|      * @param sslSocket Instance of the SSL socket to use in connection with server. | ||||
|      * @return Method to call to indicate the server name of interest to the server. | ||||
|      */ | ||||
|     private static Method getMethod(SSLSocket sslSocket) { | ||||
|         final Class<?> sslSocketClass = sslSocket.getClass(); | ||||
|         final ServerNameIndicator instance = mSingleInstance.get(); | ||||
|         if (instance == null) { | ||||
|             return initFrom(sslSocketClass); | ||||
| 
 | ||||
|         } else if (instance.mSSLSocketClassRef.get() != sslSocketClass) { | ||||
|             // the underlying class changed | ||||
|             return initFrom(sslSocketClass); | ||||
| 
 | ||||
|         } else if (instance.mSetHostnameMethodRef == null) { | ||||
|             // SNI not supported | ||||
|             return null; | ||||
| 
 | ||||
|         } else { | ||||
|             final Method cachedSetHostnameMethod = instance.mSetHostnameMethodRef.get(); | ||||
|             return (cachedSetHostnameMethod == null) ? initFrom(sslSocketClass) : cachedSetHostnameMethod; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Singleton initializer. | ||||
|      * <p> | ||||
|      * Uses reflection to extract and 'cache' the method to invoke to indicate the desited host name to the server side. | ||||
|      * | ||||
|      * @param sslSocketClass Underlying class providing the implementation of {@link SSLSocket}. | ||||
|      * @return Method to call to indicate the server name of interest to the server. | ||||
|      */ | ||||
|     private static Method initFrom(Class<?> sslSocketClass) { | ||||
|         Log_OC.i(TAG, "SSLSocket implementation: " + sslSocketClass.getCanonicalName()); | ||||
| 		Method setHostnameMethod = null; | ||||
| 		try { | ||||
| 			setHostnameMethod = sslSocketClass.getMethod(METHOD_NAME, String.class); | ||||
| 		} catch (SecurityException e) { | ||||
| 			Log_OC.e(TAG, "Could not access to SSLSocket#setHostname(String) method ", e); | ||||
| 			 | ||||
| 		} catch (NoSuchMethodException e) { | ||||
| 			Log_OC.i(TAG, "Could not find SSLSocket#setHostname(String) method - SNI not supported"); | ||||
| 		} | ||||
| 		mSingleInstance.set(new ServerNameIndicator(sslSocketClass, setHostnameMethod)); | ||||
| 		return setHostnameMethod; | ||||
| 	} | ||||
|         Method setHostnameMethod = null; | ||||
|         try { | ||||
|             setHostnameMethod = sslSocketClass.getMethod(METHOD_NAME, String.class); | ||||
|         } catch (SecurityException e) { | ||||
|             Log_OC.e(TAG, "Could not access to SSLSocket#setHostname(String) method ", e); | ||||
| 
 | ||||
|         } catch (NoSuchMethodException e) { | ||||
|             Log_OC.i(TAG, "Could not find SSLSocket#setHostname(String) method - SNI not supported"); | ||||
|         } | ||||
|         mSingleInstance.set(new ServerNameIndicator(sslSocketClass, setHostnameMethod)); | ||||
|         return setHostnameMethod; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,23 +1,23 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *   Copyright (C) 2012 Bartek Przybylski | ||||
|  *    | ||||
|  * | ||||
|  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  *   of this software and associated documentation files (the "Software"), to deal | ||||
|  *   in the Software without restriction, including without limitation the rights | ||||
|  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  *   copies of the Software, and to permit persons to whom the Software is | ||||
|  *   furnished to do so, subject to the following conditions: | ||||
|  *    | ||||
|  * | ||||
|  *   The above copyright notice and this permission notice shall be included in | ||||
|  *   all copies or substantial portions of the Software. | ||||
|  *    | ||||
|  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -25,64 +25,64 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.network; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| 
 | ||||
| import java.text.ParseException; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| 
 | ||||
| public class WebdavUtils { | ||||
|     public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat( | ||||
|             "dd.MM.yyyy hh:mm"); | ||||
|      | ||||
| 
 | ||||
|     private static final SimpleDateFormat DATETIME_FORMATS[] = { | ||||
|     	new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US), | ||||
|     	new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),	 | ||||
| 		new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US), | ||||
| 		new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US), | ||||
| 		new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US), | ||||
| 		new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), | ||||
| 		new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US), | ||||
| 		new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.US) | ||||
| 	}; | ||||
|             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US), | ||||
|             new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US), | ||||
|             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US), | ||||
|             new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US), | ||||
|             new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US), | ||||
|             new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), | ||||
|             new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US), | ||||
|             new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.US) | ||||
|     }; | ||||
| 
 | ||||
|     public static Date parseResponseDate(String date) { | ||||
|         Date returnDate = null; | ||||
|         SimpleDateFormat format = null; | ||||
|         for (int i = 0; i < DATETIME_FORMATS.length; ++i) { | ||||
|             try { | ||||
|             	format = DATETIME_FORMATS[i]; | ||||
|             	synchronized(format) { | ||||
|             		returnDate = format.parse(date); | ||||
|             	} | ||||
|                 format = DATETIME_FORMATS[i]; | ||||
|                 synchronized (format) { | ||||
|                     returnDate = format.parse(date); | ||||
|                 } | ||||
|                 return returnDate; | ||||
|             } catch (ParseException e) { | ||||
|             	// this is not the format | ||||
|                 // this is not the format | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Encodes a path according to URI RFC 2396.  | ||||
|      *  | ||||
|      * Encodes a path according to URI RFC 2396. | ||||
|      * <p> | ||||
|      * If the received path doesn't start with "/", the method adds it. | ||||
|      *  | ||||
|      * @param remoteFilePath    Path | ||||
|      * @return                  Encoded path according to RFC 2396, always starting with "/" | ||||
|      * | ||||
|      * @param remoteFilePath Path | ||||
|      * @return Encoded path according to RFC 2396, always starting with "/" | ||||
|      */ | ||||
|     public static String encodePath(String remoteFilePath) { | ||||
|         String encodedPath = Uri.encode(remoteFilePath, "/"); | ||||
|         if (!encodedPath.startsWith("/")) | ||||
|         if (!encodedPath.startsWith("/")) { | ||||
|             encodedPath = "/" + encodedPath; | ||||
|         } | ||||
|         return encodedPath; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * @param rawEtag | ||||
|      * @return | ||||
|      */ | ||||
| @ -100,7 +100,6 @@ public class WebdavUtils { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * | ||||
|      * @param httpBaseMethod from which to get the etag | ||||
|      * @return etag from response | ||||
|      */ | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2017 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -32,18 +32,17 @@ import java.lang.reflect.Method; | ||||
| import java.net.Socket; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Enforces, if possible, a write timeout for a socket. | ||||
|  * | ||||
|  * <p> | ||||
|  * Built as a singleton. | ||||
|  * | ||||
|  * <p> | ||||
|  * Tries to hit something like this: | ||||
|  * https://android.googlesource.com/platform/external/conscrypt/+/lollipop-release/src/main/java/org/conscrypt/OpenSSLSocketImpl.java#1005 | ||||
|  * | ||||
|  * <p> | ||||
|  * Minimizes the chances of getting stalled in PUT/POST request if the network interface is lost while | ||||
|  * writing the entity into the outwards sockect. | ||||
|  * | ||||
|  * <p> | ||||
|  * It happens. See https://github.com/owncloud/android/issues/1684#issuecomment-295306015 | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -56,36 +55,33 @@ public class WriteTimeoutEnforcer { | ||||
| 
 | ||||
|     private static final String METHOD_NAME = "setSoWriteTimeout"; | ||||
| 
 | ||||
| 
 | ||||
|     private final WeakReference<Class<?>> mSocketClassRef; | ||||
|     private final WeakReference<Method> mSetSoWriteTimeoutMethodRef; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Private constructor, class is a singleton. | ||||
|      * | ||||
|      * @param socketClass               Underlying implementation class of {@link Socket} used to connect | ||||
|      *                                  with the server. | ||||
|      * @param setSoWriteTimeoutMethod   Name of the method to call to set a write timeout in the socket. | ||||
|      * @param socketClass             Underlying implementation class of {@link Socket} used to connect | ||||
|      *                                with the server. | ||||
|      * @param setSoWriteTimeoutMethod Name of the method to call to set a write timeout in the socket. | ||||
|      */ | ||||
|     private WriteTimeoutEnforcer(Class<?> socketClass, Method setSoWriteTimeoutMethod) { | ||||
|         mSocketClassRef = new WeakReference<Class<?>>(socketClass); | ||||
|         mSetSoWriteTimeoutMethodRef = | ||||
|             (setSoWriteTimeoutMethod == null) ? | ||||
|                 null : | ||||
|                 new WeakReference<>(setSoWriteTimeoutMethod) | ||||
|                 (setSoWriteTimeoutMethod == null) ? | ||||
|                         null : | ||||
|                         new WeakReference<>(setSoWriteTimeoutMethod) | ||||
|         ; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Calls the {@code #setSoWrite(int)} method of the underlying implementation | ||||
|      * of {@link Socket} if exists. | ||||
| 
 | ||||
|      * <p> | ||||
|      * Creates and initializes the single instance of the class when needed | ||||
|      * | ||||
|      * @param writeTimeoutMilliseconds  Write timeout to set, in milliseconds. | ||||
|      * @param socket                    Client socket to connect with the server. | ||||
|      * @param writeTimeoutMilliseconds Write timeout to set, in milliseconds. | ||||
|      * @param socket                   Client socket to connect with the server. | ||||
|      */ | ||||
|     public static void setSoWriteTimeout(int writeTimeoutMilliseconds, Socket socket) { | ||||
|         final Method setSoWriteTimeoutMethod = getMethod(socket); | ||||
| @ -93,9 +89,9 @@ public class WriteTimeoutEnforcer { | ||||
|             try { | ||||
|                 setSoWriteTimeoutMethod.invoke(socket, writeTimeoutMilliseconds); | ||||
|                 Log_OC.i( | ||||
|                     TAG, | ||||
|                     "Write timeout set in socket, writeTimeoutMilliseconds: " | ||||
|                         + writeTimeoutMilliseconds | ||||
|                         TAG, | ||||
|                         "Write timeout set in socket, writeTimeoutMilliseconds: " | ||||
|                                 + writeTimeoutMilliseconds | ||||
|                 ); | ||||
| 
 | ||||
|             } catch (IllegalArgumentException e) { | ||||
| @ -112,13 +108,12 @@ public class WriteTimeoutEnforcer { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the method to invoke trying to minimize the cost of reflection reusing objects cached | ||||
|      * in static members. | ||||
|      * | ||||
|      * @param socket    Instance of the socket to use in connection with server. | ||||
|      * @return          Method to call to set a write timeout in the socket. | ||||
|      * @param socket Instance of the socket to use in connection with server. | ||||
|      * @return Method to call to set a write timeout in the socket. | ||||
|      */ | ||||
|     private static Method getMethod(Socket socket) { | ||||
|         final Class<?> socketClass = socket.getClass(); | ||||
| @ -137,20 +132,19 @@ public class WriteTimeoutEnforcer { | ||||
|         } else { | ||||
|             final Method cachedSetSoWriteTimeoutMethod = instance.mSetSoWriteTimeoutMethodRef.get(); | ||||
|             return (cachedSetSoWriteTimeoutMethod == null) ? | ||||
|                 initFrom(socketClass) : | ||||
|                 cachedSetSoWriteTimeoutMethod | ||||
|             ; | ||||
|                     initFrom(socketClass) : | ||||
|                     cachedSetSoWriteTimeoutMethod | ||||
|                     ; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Singleton initializer. | ||||
|      * | ||||
|      * <p> | ||||
|      * Uses reflection to extract and 'cache' the method to invoke to set a write timouet in a socket. | ||||
|      * | ||||
|      * @param socketClass   Underlying class providing the implementation of {@link Socket}. | ||||
|      * @return              Method to call to set a write timeout in the socket. | ||||
|      * @param socketClass Underlying class providing the implementation of {@link Socket}. | ||||
|      * @return Method to call to set a write timeout in the socket. | ||||
|      */ | ||||
|     private static Method initFrom(Class<?> socketClass) { | ||||
|         Log_OC.i(TAG, "Socket implementation: " + socketClass.getCanonicalName()); | ||||
| @ -162,8 +156,8 @@ public class WriteTimeoutEnforcer { | ||||
| 
 | ||||
|         } catch (NoSuchMethodException e) { | ||||
|             Log_OC.i( | ||||
|                 TAG, | ||||
|                 "Could not find (SocketImpl)#setSoWriteTimeout(int) method - write timeout not supported" | ||||
|                     TAG, | ||||
|                     "Could not find (SocketImpl)#setSoWriteTimeout(int) method - write timeout not supported" | ||||
|             ); | ||||
|         } | ||||
|         mSingleInstance.set(new WriteTimeoutEnforcer(socketClass, setSoWriteTimeoutMethod)); | ||||
|  | ||||
| @ -34,105 +34,110 @@ import java.io.InputStream; | ||||
| 
 | ||||
| /** | ||||
|  * Parser for server exceptions | ||||
|  * | ||||
|  * @author davidgonzalez | ||||
|  */ | ||||
| public class ErrorMessageParser { | ||||
| 	// No namespaces | ||||
| 	private static final String ns = null; | ||||
|     // 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_MESSAGE = "s:message"; | ||||
|     // Nodes for XML Parser | ||||
|     private static final String NODE_ERROR = "d:error"; | ||||
|     private static final String NODE_MESSAGE = "s:message"; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse exception response | ||||
| 	 * @param is | ||||
| 	 * @return errorMessage for an exception | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	public String parseXMLResponse(InputStream is) throws XmlPullParserException, | ||||
| 			IOException { | ||||
| 		String errorMessage = ""; | ||||
|     /** | ||||
|      * Parse exception response | ||||
|      * | ||||
|      * @param is | ||||
|      * @return errorMessage for an exception | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     public String parseXMLResponse(InputStream is) throws XmlPullParserException, | ||||
|             IOException { | ||||
|         String errorMessage = ""; | ||||
| 
 | ||||
| 		try { | ||||
| 			// XMLPullParser | ||||
| 			XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); | ||||
| 			factory.setNamespaceAware(true); | ||||
|         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(); | ||||
| 			errorMessage = readError(parser); | ||||
|             XmlPullParser parser = Xml.newPullParser(); | ||||
|             parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); | ||||
|             parser.setInput(is, null); | ||||
|             parser.nextTag(); | ||||
|             errorMessage = readError(parser); | ||||
| 
 | ||||
| 		} finally { | ||||
| 			is.close(); | ||||
| 		} | ||||
| 		return errorMessage; | ||||
| 	} | ||||
|         } finally { | ||||
|             is.close(); | ||||
|         } | ||||
|         return errorMessage; | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse OCS node | ||||
| 	 * @param parser | ||||
| 	 * @return reason for exception | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	private String readError (XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
| 		String errorMessage = ""; | ||||
| 		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_MESSAGE | ||||
| 			if (name.equalsIgnoreCase(NODE_MESSAGE)) { | ||||
| 				errorMessage = readText(parser); | ||||
| 			} else { | ||||
| 				skip(parser); | ||||
| 			} | ||||
| 		} | ||||
| 		return errorMessage; | ||||
| 	} | ||||
|     /** | ||||
|      * Parse OCS node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return reason for exception | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private String readError(XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
|         String errorMessage = ""; | ||||
|         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_MESSAGE | ||||
|             if (name.equalsIgnoreCase(NODE_MESSAGE)) { | ||||
|                 errorMessage = readText(parser); | ||||
|             } else { | ||||
|                 skip(parser); | ||||
|             } | ||||
|         } | ||||
|         return errorMessage; | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * 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; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|     /** | ||||
|      * 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; | ||||
| 	} | ||||
|     /** | ||||
|      * 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; | ||||
|     } | ||||
| } | ||||
| @ -35,110 +35,116 @@ 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"; | ||||
|     private static final String EXCEPTION_UPLOAD_STRING = "OCP\\Files\\InvalidPathException"; | ||||
| 
 | ||||
|     // No namespaces | ||||
| 	private static final String ns = null; | ||||
|     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"; | ||||
|     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, | ||||
|      * 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); | ||||
|         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); | ||||
|             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; | ||||
| 	} | ||||
|         } 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); | ||||
| 			} | ||||
|     /** | ||||
|      * 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); | ||||
| 	} | ||||
|         } | ||||
|         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; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|     /** | ||||
|      * 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; | ||||
| 	} | ||||
|     /** | ||||
|      * 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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,9 +24,8 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.common.operations; | ||||
| 
 | ||||
| 
 | ||||
| public interface OnRemoteOperationListener { | ||||
| 
 | ||||
| 	void onRemoteOperationFinish(RemoteOperation caller, RemoteOperationResult result); | ||||
| 	 | ||||
|     void onRemoteOperationFinish(RemoteOperation caller, RemoteOperationResult result); | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
|  | ||||
| @ -12,25 +12,21 @@ import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.OwnCloudClientManagerFactory; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import okhttp3.OkHttpClient; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import okhttp3.OkHttpClient; | ||||
| 
 | ||||
| public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     private static final String TAG = RemoteOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     /** | ||||
|      * OCS API header name | ||||
|      */ | ||||
|     public static final String OCS_API_HEADER = "OCS-APIREQUEST"; | ||||
| 
 | ||||
|     /** | ||||
|      * OCS API header value | ||||
|      */ | ||||
|     public static final String OCS_API_HEADER_VALUE = "true"; | ||||
| 
 | ||||
|     private static final String TAG = RemoteOperation.class.getSimpleName(); | ||||
|     /** | ||||
|      * ownCloud account in the remote ownCloud server to operate | ||||
|      */ | ||||
| @ -61,10 +57,9 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      */ | ||||
|     protected Handler mListenerHandler = null; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Asynchronously executes the remote operation | ||||
|      * | ||||
|      * <p> | ||||
|      * This method should be used whenever an ownCloud account is available, | ||||
|      * instead of {@link #execute(OwnCloudClient, OnRemoteOperationListener, Handler))}. | ||||
|      * | ||||
| @ -79,12 +74,14 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|     public Thread execute(Account account, Context context, | ||||
|                           OnRemoteOperationListener listener, Handler listenerHandler) { | ||||
| 
 | ||||
|         if (account == null) | ||||
|         if (account == null) { | ||||
|             throw new IllegalArgumentException | ||||
|                     ("Trying to execute a remote operation with a NULL Account"); | ||||
|         if (context == null) | ||||
|         } | ||||
|         if (context == null) { | ||||
|             throw new IllegalArgumentException | ||||
|                     ("Trying to execute a remote operation with a NULL Context"); | ||||
|         } | ||||
|         // mAccount and mContext in the runnerThread to create below | ||||
|         mAccount = account; | ||||
|         mContext = context.getApplicationContext(); | ||||
| @ -99,7 +96,6 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|         return runnerThread; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Asynchronously executes the remote operation | ||||
|      * | ||||
| @ -168,9 +164,9 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronously executes the remote operation on the received ownCloud account. | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * <p> | ||||
|      * This method should be used whenever an ownCloud account is available, instead of | ||||
|      * {@link #execute(OwnCloudClient)}. | ||||
|      * | ||||
| @ -180,22 +176,23 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      * @return Result of the operation. | ||||
|      */ | ||||
|     public RemoteOperationResult<T> execute(Account account, Context context) { | ||||
|         if (account == null) | ||||
|         if (account == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "Account"); | ||||
|         if (context == null) | ||||
|         } | ||||
|         if (context == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "Context"); | ||||
|         } | ||||
|         mAccount = account; | ||||
|         mContext = context.getApplicationContext(); | ||||
| 
 | ||||
|         return runOperation(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronously executes the remote operation | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * @param client Client object to reach an ownCloud server during the execution of | ||||
| @ -203,9 +200,10 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      * @return Result of the operation. | ||||
|      */ | ||||
|     public RemoteOperationResult<T> execute(OwnCloudClient client) { | ||||
|         if (client == null) | ||||
|         if (client == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "OwnCloudClient"); | ||||
|         } | ||||
|         mClient = client; | ||||
|         if (client.getAccount() != null) { | ||||
|             mAccount = client.getAccount().getSavedAccount(); | ||||
| @ -217,7 +215,7 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     /** | ||||
|      * Synchronously executes the remote operation | ||||
|      * | ||||
|      * <p> | ||||
|      * Do not call this method from the main thread. | ||||
|      * | ||||
|      * @param client Client object to reach an ownCloud server during the execution of | ||||
| @ -225,9 +223,10 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
|      * @return Result of the operation. | ||||
|      */ | ||||
|     public RemoteOperationResult<T> execute(OkHttpClient client, Context context) { | ||||
|         if (client == null) | ||||
|         if (client == null) { | ||||
|             throw new IllegalArgumentException("Trying to execute a remote operation with a NULL " + | ||||
|                     "OwnCloudClient"); | ||||
|         } | ||||
|         mHttpClient = client; | ||||
|         mContext = context; | ||||
| 
 | ||||
| @ -236,12 +235,12 @@ public abstract class RemoteOperation<T extends Object> implements Runnable { | ||||
| 
 | ||||
|     /** | ||||
|      * Run operation for asynchronous or synchronous 'onExecute' method. | ||||
|      * | ||||
|      * <p> | ||||
|      * Considers and performs silent refresh of account credentials if possible, and if | ||||
|      * {@link RemoteOperation#setSilentRefreshOfAccountCredentials(boolean)} was called with | ||||
|      * parameter 'true' before the execution. | ||||
|      * | ||||
|      * @return      Remote operation result | ||||
|      * @return Remote operation result | ||||
|      */ | ||||
|     private RemoteOperationResult<T> runOperation() { | ||||
| 
 | ||||
|  | ||||
| @ -27,14 +27,18 @@ package com.owncloud.android.lib.common.operations; | ||||
| import android.accounts.Account; | ||||
| import android.accounts.AccountsException; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.DavException; | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.HttpBaseMethod; | ||||
| import com.owncloud.android.lib.common.network.CertificateCombinedException; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| 
 | ||||
| import okhttp3.Headers; | ||||
| import org.json.JSONException; | ||||
| 
 | ||||
| import javax.net.ssl.SSLException; | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.IOException; | ||||
| @ -48,13 +52,6 @@ import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| import javax.net.ssl.SSLException; | ||||
| import javax.net.ssl.SSLPeerUnverifiedException; | ||||
| 
 | ||||
| import at.bitfire.dav4android.exception.DavException; | ||||
| import at.bitfire.dav4android.exception.HttpException; | ||||
| import okhttp3.Headers; | ||||
| 
 | ||||
| public class RemoteOperationResult<T extends Object> | ||||
|         implements Serializable { | ||||
| 
 | ||||
| @ -64,61 +61,6 @@ public class RemoteOperationResult<T extends Object> | ||||
|     private static final long serialVersionUID = 4968939884332372230L; | ||||
| 
 | ||||
|     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, | ||||
|         SSL_ERROR, | ||||
|         SSL_RECOVERABLE_PEER_UNVERIFIED, | ||||
|         BAD_OC_VERSION, | ||||
|         CANCELLED, | ||||
|         INVALID_LOCAL_FILE_NAME, | ||||
|         INVALID_OVERWRITE, | ||||
|         CONFLICT, | ||||
|         OAUTH2_ERROR, | ||||
|         SYNC_CONFLICT, | ||||
|         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, | ||||
|         ACCOUNT_NOT_THE_SAME, | ||||
|         INVALID_CHARACTER_IN_NAME, | ||||
|         SHARE_NOT_FOUND, | ||||
|         LOCAL_STORAGE_NOT_REMOVED, | ||||
|         FORBIDDEN, | ||||
|         SHARE_FORBIDDEN, | ||||
|         SPECIFIC_FORBIDDEN, | ||||
|         OK_REDIRECT_TO_NON_SECURE_CONNECTION, | ||||
|         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, | ||||
|         DELAYED_FOR_WIFI, | ||||
|         LOCAL_FILE_NOT_FOUND, | ||||
|         SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_UNSUPPORTED_MEDIA_TYPE, | ||||
|         SPECIFIC_METHOD_NOT_ALLOWED | ||||
|     } | ||||
| 
 | ||||
|     private boolean mSuccess = false; | ||||
|     private int mHttpCode = -1; | ||||
|     private String mHttpPhrase = null; | ||||
| @ -128,10 +70,9 @@ public class RemoteOperationResult<T extends Object> | ||||
|     private ArrayList<String> mAuthenticate = new ArrayList<>(); | ||||
|     private String mLastPermanentLocation = null; | ||||
|     private T mData = null; | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from result code. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation} | ||||
|      * | ||||
|      * @param code {@link ResultCode} decided by the caller. | ||||
| @ -146,6 +87,7 @@ public class RemoteOperationResult<T extends Object> | ||||
|     /** | ||||
|      * Create a new RemoteOperationResult based on the result given by a previous one. | ||||
|      * It does not copy the data. | ||||
|      * | ||||
|      * @param prevRemoteOperation | ||||
|      */ | ||||
|     public RemoteOperationResult(RemoteOperationResult prevRemoteOperation) { | ||||
| @ -161,9 +103,9 @@ public class RemoteOperationResult<T extends Object> | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from exception. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when an exception prevented the end of the {@link RemoteOperation}. | ||||
|      * | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} depending on the type of the exception. | ||||
|      * | ||||
|      * @param e Exception that interrupted the {@link RemoteOperation} | ||||
| @ -193,7 +135,7 @@ public class RemoteOperationResult<T extends Object> | ||||
|             mCode = ResultCode.ACCOUNT_EXCEPTION; | ||||
| 
 | ||||
|         } else if (e instanceof SSLException || e instanceof RuntimeException) { | ||||
|             if(e instanceof SSLPeerUnverifiedException) { | ||||
|             if (e instanceof SSLPeerUnverifiedException) { | ||||
|                 mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED; | ||||
|             } else { | ||||
|                 CertificateCombinedException se = getCertificateCombinedException(e); | ||||
| @ -220,9 +162,9 @@ public class RemoteOperationResult<T extends Object> | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from separate elements of an HTTP or DAV response. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when the result needs to be interpreted from the response of an HTTP/DAV method. | ||||
|      * | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} from the already executed method received as a parameter. Generally, | ||||
|      * will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the | ||||
|      * response body | ||||
| @ -285,44 +227,18 @@ public class RemoteOperationResult<T extends Object> | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse the error message included in the body response, if any, and set the specific result | ||||
|      * code | ||||
|      * | ||||
|      * @param bodyResponse okHttp response body | ||||
|      * @param resultCode our own custom result code | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) { | ||||
| 
 | ||||
|         if (bodyResponse != null && bodyResponse.length() > 0) { | ||||
|             InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); | ||||
|             ErrorMessageParser xmlParser = new ErrorMessageParser(); | ||||
|             try { | ||||
|                 String errorMessage = xmlParser.parseXMLResponse(is); | ||||
|                 if (errorMessage != "" && errorMessage != null) { | ||||
|                     mCode = resultCode; | ||||
|                     mHttpPhrase = errorMessage; | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); | ||||
|                 // mCode stays as set in this(success, httpCode, headers) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Public constructor from separate elements of an HTTP or DAV response. | ||||
|      * | ||||
|      * <p> | ||||
|      * To be used when the result needs to be interpreted from HTTP response elements that could come from | ||||
|      * different requests (WARNING: black magic, try to avoid). | ||||
|      * | ||||
|      * | ||||
|      * <p> | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received. | ||||
|      * | ||||
|      * @param httpCode    HTTP status code returned by an HTTP/DAV method. | ||||
|      * @param httpPhrase  HTTP status line phrase returned by an HTTP/DAV method | ||||
|      * @param headers HTTP response header returned by an HTTP/DAV method | ||||
|      * @param httpCode   HTTP status code returned by an HTTP/DAV method. | ||||
|      * @param httpPhrase HTTP status line phrase returned by an HTTP/DAV method | ||||
|      * @param headers    HTTP response header returned by an HTTP/DAV method | ||||
|      */ | ||||
|     public RemoteOperationResult(int httpCode, String httpPhrase, Headers headers) { | ||||
|         this(httpCode, httpPhrase); | ||||
| @ -345,7 +261,7 @@ public class RemoteOperationResult<T extends Object> | ||||
| 
 | ||||
|     /** | ||||
|      * Private constructor for results built interpreting a HTTP or DAV response. | ||||
|      * | ||||
|      * <p> | ||||
|      * Determines a {@link ResultCode} depending of the type of the exception. | ||||
|      * | ||||
|      * @param httpCode   HTTP status code returned by the HTTP/DAV method. | ||||
| @ -389,11 +305,40 @@ public class RemoteOperationResult<T extends Object> | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse the error message included in the body response, if any, and set the specific result | ||||
|      * code | ||||
|      * | ||||
|      * @param bodyResponse okHttp response body | ||||
|      * @param resultCode   our own custom result code | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) { | ||||
| 
 | ||||
|         if (bodyResponse != null && bodyResponse.length() > 0) { | ||||
|             InputStream is = new ByteArrayInputStream(bodyResponse.getBytes()); | ||||
|             ErrorMessageParser xmlParser = new ErrorMessageParser(); | ||||
|             try { | ||||
|                 String errorMessage = xmlParser.parseXMLResponse(is); | ||||
|                 if (errorMessage != "" && errorMessage != null) { | ||||
|                     mCode = resultCode; | ||||
|                     mHttpPhrase = errorMessage; | ||||
|                 } | ||||
|             } catch (Exception e) { | ||||
|                 Log_OC.w(TAG, "Error reading exception from server: " + e.getMessage()); | ||||
|                 // mCode stays as set in this(success, httpCode, headers) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean isSuccess() { | ||||
|         return mSuccess; | ||||
|     } | ||||
| 
 | ||||
|     public void setSuccess(boolean success) { | ||||
|         this.mSuccess = success; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isCancelled() { | ||||
|         return mCode == ResultCode.CANCELLED; | ||||
|     } | ||||
| @ -459,10 +404,11 @@ public class RemoteOperationResult<T extends Object> | ||||
|                 return "Unknown host exception"; | ||||
| 
 | ||||
|             } else if (mException instanceof CertificateCombinedException) { | ||||
|                 if (((CertificateCombinedException) mException).isRecoverable()) | ||||
|                 if (((CertificateCombinedException) mException).isRecoverable()) { | ||||
|                     return "SSL recoverable exception"; | ||||
|                 else | ||||
|                 } else { | ||||
|                     return "SSL exception"; | ||||
|                 } | ||||
| 
 | ||||
|             } else if (mException instanceof SSLException) { | ||||
|                 return "SSL exception"; | ||||
| @ -572,15 +518,65 @@ public class RemoteOperationResult<T extends Object> | ||||
|         mLastPermanentLocation = lastPermanentLocation; | ||||
|     } | ||||
| 
 | ||||
|     public void setSuccess(boolean success) { | ||||
|         this.mSuccess = success; | ||||
|     public T getData() { | ||||
|         return mData; | ||||
|     } | ||||
| 
 | ||||
|     public void setData(T data) { | ||||
|         mData = data; | ||||
|     } | ||||
| 
 | ||||
|     public T getData() { | ||||
|         return mData; | ||||
|     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, | ||||
|         SSL_ERROR, | ||||
|         SSL_RECOVERABLE_PEER_UNVERIFIED, | ||||
|         BAD_OC_VERSION, | ||||
|         CANCELLED, | ||||
|         INVALID_LOCAL_FILE_NAME, | ||||
|         INVALID_OVERWRITE, | ||||
|         CONFLICT, | ||||
|         OAUTH2_ERROR, | ||||
|         SYNC_CONFLICT, | ||||
|         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, | ||||
|         ACCOUNT_NOT_THE_SAME, | ||||
|         INVALID_CHARACTER_IN_NAME, | ||||
|         SHARE_NOT_FOUND, | ||||
|         LOCAL_STORAGE_NOT_REMOVED, | ||||
|         FORBIDDEN, | ||||
|         SHARE_FORBIDDEN, | ||||
|         SPECIFIC_FORBIDDEN, | ||||
|         OK_REDIRECT_TO_NON_SECURE_CONNECTION, | ||||
|         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, | ||||
|         DELAYED_FOR_WIFI, | ||||
|         LOCAL_FILE_NOT_FOUND, | ||||
|         SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_SERVICE_UNAVAILABLE, | ||||
|         SPECIFIC_UNSUPPORTED_MEDIA_TYPE, | ||||
|         SPECIFIC_METHOD_NOT_ALLOWED | ||||
|     } | ||||
| } | ||||
| @ -39,7 +39,6 @@ public class RandomUtils { | ||||
| 
 | ||||
|     /** | ||||
|      * @param length the number of random chars to be generated | ||||
|      * | ||||
|      * @return String containing random chars | ||||
|      */ | ||||
|     public static String generateRandomString(int length) { | ||||
| @ -59,7 +58,7 @@ public class RandomUtils { | ||||
|      */ | ||||
|     public static int generateRandomInteger(int min, int max) { | ||||
|         Random r = new Random(); | ||||
|         return r.nextInt(max-min) + min; | ||||
|         return r.nextInt(max - min) + min; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -30,9 +30,9 @@ import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.CopyMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| 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 java.net.URL; | ||||
| @ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit; | ||||
| /** | ||||
|  * 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 | ||||
| @ -112,14 +112,13 @@ public class CopyRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|             final int status = client.executeHttpMethod(copyMethod); | ||||
| 
 | ||||
|             if(status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT) { | ||||
|             if (status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT) { | ||||
|                 result = new RemoteOperationResult<>(ResultCode.OK); | ||||
|             } else if (status == HttpConstants.HTTP_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 | ||||
| 
 | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,23 +24,21 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.files; | ||||
| 
 | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.MkColMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| 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; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Remote operation performing the creation of a new folder in the ownCloud server. | ||||
|  * | ||||
| @ -60,6 +58,7 @@ 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. | ||||
|      */ | ||||
| @ -79,12 +78,12 @@ public class CreateRemoteFolderOperation extends RemoteOperation { | ||||
|         RemoteOperationResult result; | ||||
|         OwnCloudVersion version = client.getOwnCloudVersion(); | ||||
|         boolean versionWithForbiddenChars = | ||||
|             (version != null && version.isVersionWithForbiddenCharacters()); | ||||
|                 (version != null && version.isVersionWithForbiddenCharacters()); | ||||
|         boolean noInvalidChars = FileUtils.isValidPath(mRemotePath, versionWithForbiddenChars); | ||||
|         if (noInvalidChars) { | ||||
|             result = createFolder(client); | ||||
|             if (!result.isSuccess() && mCreateFullPath && | ||||
|                 RemoteOperationResult.ResultCode.CONFLICT == result.getCode()) { | ||||
|                     RemoteOperationResult.ResultCode.CONFLICT == result.getCode()) { | ||||
|                 result = createParentFolder(FileUtils.getParentPath(mRemotePath), client); | ||||
|                 if (result.isSuccess()) { | ||||
|                     result = createFolder(client);    // second (and last) try | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -56,9 +56,8 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|     private static final String TAG = DownloadRemoteFileOperation.class.getSimpleName(); | ||||
|     private static final int FORBIDDEN_ERROR = 403; | ||||
|     private static final int SERVICE_UNAVAILABLE_ERROR = 503; | ||||
| 
 | ||||
|     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<>(); | ||||
|     private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); | ||||
|     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<>(); | ||||
|     private long mModificationTimestamp = 0; | ||||
|     private String mEtag = ""; | ||||
|     private GetMethod mGet; | ||||
| @ -83,18 +82,17 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|             tmpFile.getParentFile().mkdirs(); | ||||
|             result = downloadFile(client, tmpFile); | ||||
|             Log_OC.i(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + | ||||
|                 result.getLogMessage()); | ||||
|                     result.getLogMessage()); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             result = new RemoteOperationResult<>(e); | ||||
|             Log_OC.e(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " + | ||||
|                 result.getLogMessage(), e); | ||||
|                     result.getLogMessage(), e); | ||||
|         } | ||||
| 
 | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private RemoteOperationResult downloadFile(OwnCloudClient client, File targetFile) throws | ||||
|             Exception { | ||||
| 
 | ||||
| @ -118,8 +116,8 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|                 long totalToTransfer = | ||||
|                         (contentLength != null | ||||
|                                 && contentLength.length() > 0) | ||||
|                         ? Long.parseLong(contentLength) | ||||
|                         : 0; | ||||
|                                 ? Long.parseLong(contentLength) | ||||
|                                 : 0; | ||||
| 
 | ||||
|                 byte[] bytes = new byte[4096]; | ||||
|                 int readResult; | ||||
| @ -136,7 +134,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|                         it = mDataTransferListeners.iterator(); | ||||
|                         while (it.hasNext()) { | ||||
|                             it.next().onTransferProgress(readResult, transferred, totalToTransfer, | ||||
|                                 targetFile.getName()); | ||||
|                                     targetFile.getName()); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @ -144,8 +142,8 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|                     savedFile = true; | ||||
|                     final String modificationTime = | ||||
|                             mGet.getResponseHeaders().get("Last-Modified") != null | ||||
|                             ? mGet.getResponseHeaders().get("Last-Modified") | ||||
|                             :  mGet.getResponseHeader("last-modified"); | ||||
|                                     ? mGet.getResponseHeaders().get("Last-Modified") | ||||
|                                     : mGet.getResponseHeader("last-modified"); | ||||
| 
 | ||||
|                     if (modificationTime != null) { | ||||
|                         final Date d = WebdavUtils.parseResponseDate(modificationTime); | ||||
| @ -177,8 +175,12 @@ public class DownloadRemoteFileOperation extends RemoteOperation { | ||||
|                     ? new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK) | ||||
|                     : new RemoteOperationResult<>(mGet); | ||||
|         } finally { | ||||
|             if (fos != null) fos.close(); | ||||
|             if (bis != null) bis.close(); | ||||
|             if (fos != null) { | ||||
|                 fos.close(); | ||||
|             } | ||||
|             if (bis != null) { | ||||
|                 bis.close(); | ||||
|             } | ||||
|             if (!savedFile && targetFile.exists()) { | ||||
|                 targetFile.delete(); | ||||
|             } | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -30,55 +30,56 @@ import java.io.File; | ||||
| 
 | ||||
| public class FileUtils { | ||||
| 
 | ||||
| 	private static final  String TAG = FileUtils.class.getSimpleName(); | ||||
|     public static final String PATH_SEPARATOR = "/"; | ||||
|     public static final String FINAL_CHUNKS_FILE = ".file"; | ||||
|     private static final String TAG = FileUtils.class.getSimpleName(); | ||||
| 
 | ||||
| 	public static final String PATH_SEPARATOR = "/"; | ||||
| 	public static final String FINAL_CHUNKS_FILE = ".file"; | ||||
|     public static String getParentPath(String remotePath) { | ||||
|         String parentPath = new File(remotePath).getParent(); | ||||
|         parentPath = parentPath.endsWith(PATH_SEPARATOR) ? parentPath : parentPath + PATH_SEPARATOR; | ||||
|         return parentPath; | ||||
|     } | ||||
| 
 | ||||
| 	public static String getParentPath(String remotePath) { | ||||
| 		String parentPath = new File(remotePath).getParent(); | ||||
| 		parentPath = parentPath.endsWith(PATH_SEPARATOR) ? parentPath : parentPath + PATH_SEPARATOR; | ||||
| 		return parentPath; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , | ||||
| 	 * : , " , | , ? , * | ||||
| 	 * @param fileName | ||||
| 	 * @param versionSupportsForbiddenChars | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) { | ||||
| 		boolean result = true; | ||||
| 		 | ||||
| 		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("*") ) ) ) { | ||||
|     /** | ||||
|      * Validate the fileName to detect if contains any forbidden character: / , \ , < , > , | ||||
|      * : , " , | , ? , * | ||||
|      * | ||||
|      * @param fileName | ||||
|      * @param versionSupportsForbiddenChars | ||||
|      * @return | ||||
|      */ | ||||
|     public static boolean isValidName(String fileName, boolean versionSupportsForbiddenChars) { | ||||
|         boolean result = true; | ||||
| 
 | ||||
| 			result = false; | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , | ||||
| 	 * ? , * | ||||
| 	 * @param path | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) { | ||||
| 		boolean result = true; | ||||
| 		 | ||||
| 		Log_OC.d(TAG, "path ....... " + path); | ||||
| 		if (!versionSupportsForbidenChars && | ||||
| 				(path.contains("\\") || path.contains("<") || path.contains(">") || | ||||
| 				path.contains(":") || path.contains("\"") || path.contains("|") ||  | ||||
| 				path.contains("?") || path.contains("*") ) ){ | ||||
| 			result = false; | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
|         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("*")))) { | ||||
| 
 | ||||
|             result = false; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Validate the path to detect if contains any forbidden character: \ , < , > , : , " , | , | ||||
|      * ? , * | ||||
|      * | ||||
|      * @param path | ||||
|      * @return | ||||
|      */ | ||||
|     public static boolean isValidPath(String path, boolean versionSupportsForbidenChars) { | ||||
|         boolean result = true; | ||||
| 
 | ||||
|         Log_OC.d(TAG, "path ....... " + path); | ||||
|         if (!versionSupportsForbidenChars && | ||||
|                 (path.contains("\\") || path.contains("<") || path.contains(">") || | ||||
|                         path.contains(":") || path.contains("\"") || path.contains("|") || | ||||
|                         path.contains("?") || path.contains("*"))) { | ||||
|             result = false; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -31,9 +31,9 @@ import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.MoveMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| 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 java.net.URL; | ||||
| @ -42,7 +42,7 @@ import java.util.concurrent.TimeUnit; | ||||
| /** | ||||
|  * 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 | ||||
| @ -65,7 +65,7 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * <p> | ||||
|      * TODO Paths should finish in "/" in the case of folders. ? | ||||
|      * | ||||
|      * @param srcRemotePath    Remote path of the file/folder to move. | ||||
| @ -90,7 +90,7 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|         OwnCloudVersion version = client.getOwnCloudVersion(); | ||||
|         boolean versionWithForbiddenChars = | ||||
|             (version != null && version.isVersionWithForbiddenCharacters()); | ||||
|                 (version != null && version.isVersionWithForbiddenCharacters()); | ||||
| 
 | ||||
|         /// check parameters | ||||
|         if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) { | ||||
| @ -115,7 +115,7 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|             final MoveMethod move = new MoveMethod( | ||||
|                     new URL(srcWebDavUri + WebdavUtils.encodePath(mSrcRemotePath)), | ||||
|                 client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mTargetRemotePath), | ||||
|                     client.getUserFilesWebDavUri() + WebdavUtils.encodePath(mTargetRemotePath), | ||||
|                     mOverwrite); | ||||
| 
 | ||||
|             if (moveChunkedFile) { | ||||
| @ -128,7 +128,7 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|             final int status = client.executeHttpMethod(move); | ||||
|             /// process response | ||||
|             if(isSuccess(status)) { | ||||
|             if (isSuccess(status)) { | ||||
|                 result = new RemoteOperationResult<>(ResultCode.OK); | ||||
|             } else if (status == HttpConstants.HTTP_PRECONDITION_FAILED && !mOverwrite) { | ||||
| 
 | ||||
| @ -144,12 +144,12 @@ public class MoveRemoteFileOperation extends RemoteOperation { | ||||
|             } | ||||
| 
 | ||||
|             Log.i(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + | ||||
|                 result.getLogMessage()); | ||||
|                     result.getLogMessage()); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             result = new RemoteOperationResult<>(e); | ||||
|             Log.e(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " + | ||||
|                 result.getLogMessage(), e); | ||||
|                     result.getLogMessage(), e); | ||||
|         } | ||||
| 
 | ||||
|         return result; | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -102,7 +102,7 @@ public class ReadRemoteFileOperation extends RemoteOperation<RemoteFile> { | ||||
|             result = new RemoteOperationResult<>(e); | ||||
|             e.printStackTrace(); | ||||
|             Log_OC.e(TAG, "Synchronizing  file " + mRemotePath + ": " + result.getLogMessage(), | ||||
|                 result.getException()); | ||||
|                     result.getException()); | ||||
|         } | ||||
| 
 | ||||
|         return result; | ||||
|  | ||||
| @ -24,6 +24,7 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.files; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Response; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.accounts.AccountUtils; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| @ -38,8 +39,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import java.net.URL; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Response; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| /** | ||||
| @ -103,7 +102,7 @@ public class ReadRemoteFolderOperation extends RemoteOperation<ArrayList<RemoteF | ||||
|                 result.setData(mFolderAndFiles); | ||||
| 
 | ||||
|             } else { // synchronization failed | ||||
|                 result = new RemoteOperationResult<> (propfindMethod); | ||||
|                 result = new RemoteOperationResult<>(propfindMethod); | ||||
|             } | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -28,10 +28,6 @@ import android.net.Uri; | ||||
| import android.os.Parcel; | ||||
| import android.os.Parcelable; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.Response; | ||||
| import at.bitfire.dav4android.property.CreationDate; | ||||
| @ -47,6 +43,10 @@ import at.bitfire.dav4android.property.owncloud.OCPrivatelink; | ||||
| import at.bitfire.dav4android.property.owncloud.OCSize; | ||||
| import okhttp3.HttpUrl; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| import java.math.BigDecimal; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4_0; | ||||
| 
 | ||||
| /** | ||||
| @ -58,11 +58,24 @@ import static com.owncloud.android.lib.common.OwnCloudClient.WEBDAV_FILES_PATH_4 | ||||
| 
 | ||||
| public class RemoteFile implements Parcelable, Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() { | ||||
|         @Override | ||||
|         public RemoteFile createFromParcel(Parcel source) { | ||||
|             return new RemoteFile(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public RemoteFile[] newArray(int size) { | ||||
|             return new RemoteFile[size]; | ||||
|         } | ||||
|     }; | ||||
|     /** | ||||
|      * Generated - should be refreshed every time the class changes!! | ||||
|      */ | ||||
|     private static final long serialVersionUID = -8965995357413958539L; | ||||
|      | ||||
|     private String mRemotePath; | ||||
|     private String mMimeType; | ||||
|     private long mLength; | ||||
| @ -76,6 +89,100 @@ public class RemoteFile implements Parcelable, Serializable { | ||||
|     private BigDecimal mQuotaAvailableBytes; | ||||
|     private String mPrivateLink; | ||||
| 
 | ||||
|     public RemoteFile() { | ||||
|         resetData(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create new {@link RemoteFile} with given path. | ||||
|      * <p> | ||||
|      * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'. | ||||
|      * | ||||
|      * @param path The remote path of the file. | ||||
|      */ | ||||
|     public RemoteFile(String path) { | ||||
|         resetData(); | ||||
|         if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) { | ||||
|             throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path); | ||||
|         } | ||||
|         mRemotePath = path; | ||||
|         mCreationTimestamp = 0; | ||||
|         mLength = 0; | ||||
|         mMimeType = "DIR"; | ||||
|         mQuotaUsedBytes = BigDecimal.ZERO; | ||||
|         mQuotaAvailableBytes = BigDecimal.ZERO; | ||||
|         mPrivateLink = null; | ||||
|     } | ||||
| 
 | ||||
|     public RemoteFile(final Response davResource, String userId) { | ||||
|         this(getRemotePathFromUrl(davResource.getHref(), userId)); | ||||
|         final List<Property> properties = davResource.getProperties(); | ||||
| 
 | ||||
|         for (Property property : properties) { | ||||
|             if (property instanceof CreationDate) { | ||||
|                 this.setCreationTimestamp( | ||||
|                         Long.parseLong(((CreationDate) property).getCreationDate())); | ||||
|             } | ||||
|             if (property instanceof GetContentLength) { | ||||
|                 this.setLength(((GetContentLength) property).getContentLength()); | ||||
|             } | ||||
|             if (property instanceof GetContentType) { | ||||
|                 this.setMimeType(((GetContentType) property).getType()); | ||||
|             } | ||||
|             if (property instanceof GetLastModified) { | ||||
|                 this.setModifiedTimestamp(((GetLastModified) property).getLastModified()); | ||||
|             } | ||||
|             if (property instanceof GetETag) { | ||||
|                 this.setEtag(((GetETag) property).getETag()); | ||||
|             } | ||||
|             if (property instanceof OCPermissions) { | ||||
|                 this.setPermissions(((OCPermissions) property).getPermission()); | ||||
|             } | ||||
|             if (property instanceof OCId) { | ||||
|                 this.setRemoteId(((OCId) property).getId()); | ||||
|             } | ||||
|             if (property instanceof OCSize) { | ||||
|                 this.setSize(((OCSize) property).getSize()); | ||||
|             } | ||||
|             if (property instanceof QuotaUsedBytes) { | ||||
|                 this.setQuotaUsedBytes( | ||||
|                         BigDecimal.valueOf(((QuotaUsedBytes) property).getQuotaUsedBytes())); | ||||
|             } | ||||
|             if (property instanceof QuotaAvailableBytes) { | ||||
|                 this.setQuotaAvailableBytes( | ||||
|                         BigDecimal.valueOf(((QuotaAvailableBytes) property).getQuotaAvailableBytes())); | ||||
|             } | ||||
|             if (property instanceof OCPrivatelink) { | ||||
|                 this.setPrivateLink(((OCPrivatelink) property).getLink()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected RemoteFile(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieves a relative path from a remote file url | ||||
|      * <p> | ||||
|      * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt | ||||
|      * | ||||
|      * @param url    remote file url | ||||
|      * @param userId file owner | ||||
|      * @return remote relative path of the file | ||||
|      */ | ||||
|     private static String getRemotePathFromUrl(HttpUrl url, String userId) { | ||||
|         final String davFilesPath = WEBDAV_FILES_PATH_4_0 + userId; | ||||
|         final String absoluteDavPath = Uri.decode(url.encodedPath()); | ||||
|         final String pathToOc = absoluteDavPath.split(davFilesPath)[0]; | ||||
|         return absoluteDavPath.replace(pathToOc + davFilesPath, ""); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Getters and Setters | ||||
|      */ | ||||
| @ -168,80 +275,6 @@ public class RemoteFile implements Parcelable, Serializable { | ||||
|         mPrivateLink = privateLink; | ||||
|     } | ||||
| 
 | ||||
|     public RemoteFile() { | ||||
|         resetData(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create new {@link RemoteFile} with given path. | ||||
|      * | ||||
|      * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'. | ||||
|      * | ||||
|      * @param path The remote path of the file. | ||||
|      */ | ||||
|     public RemoteFile(String path) { | ||||
|         resetData(); | ||||
|         if (path == null || path.length() <= 0 || !path.startsWith(FileUtils.PATH_SEPARATOR)) { | ||||
|             throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path); | ||||
|         } | ||||
|         mRemotePath = path; | ||||
|         mCreationTimestamp = 0; | ||||
|         mLength = 0; | ||||
|         mMimeType = "DIR"; | ||||
|         mQuotaUsedBytes = BigDecimal.ZERO; | ||||
|         mQuotaAvailableBytes = BigDecimal.ZERO; | ||||
|         mPrivateLink = null; | ||||
|     } | ||||
| 
 | ||||
|     public RemoteFile(final Response davResource, String userId) { | ||||
|         this(getRemotePathFromUrl(davResource.getHref(), userId)); | ||||
|         final List<Property> properties = davResource.getProperties(); | ||||
| 
 | ||||
|         for(Property property : properties) { | ||||
|             if(property instanceof CreationDate) | ||||
|                 this.setCreationTimestamp( | ||||
|                         Long.parseLong(((CreationDate) property).getCreationDate())); | ||||
|             if(property instanceof GetContentLength) | ||||
|                 this.setLength(((GetContentLength) property).getContentLength()); | ||||
|             if(property instanceof  GetContentType) | ||||
|                 this.setMimeType(((GetContentType) property).getType()); | ||||
|             if(property instanceof GetLastModified) | ||||
|                 this.setModifiedTimestamp(((GetLastModified) property).getLastModified()); | ||||
|             if(property instanceof GetETag) | ||||
|                 this.setEtag(((GetETag) property).getETag()); | ||||
|             if(property instanceof OCPermissions) | ||||
|                 this.setPermissions(((OCPermissions) property).getPermission()); | ||||
|             if(property instanceof OCId) | ||||
|                 this.setRemoteId(((OCId) property).getId()); | ||||
|             if(property instanceof OCSize) | ||||
|                 this.setSize(((OCSize) property).getSize()); | ||||
|             if(property instanceof  QuotaUsedBytes) | ||||
|                 this.setQuotaUsedBytes( | ||||
|                         BigDecimal.valueOf(((QuotaUsedBytes) property).getQuotaUsedBytes())); | ||||
|             if(property instanceof QuotaAvailableBytes) | ||||
|                 this.setQuotaAvailableBytes( | ||||
|                         BigDecimal.valueOf(((QuotaAvailableBytes) property).getQuotaAvailableBytes())); | ||||
|             if(property instanceof OCPrivatelink) | ||||
|                 this.setPrivateLink(((OCPrivatelink) property).getLink()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Retrieves a relative path from a remote file url | ||||
|      * | ||||
|      * Example: url:port/remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt | ||||
|      * | ||||
|      * @param url remote file url | ||||
|      * @param userId file owner | ||||
|      * @return remote relative path of the file | ||||
|      */ | ||||
|     private static String getRemotePathFromUrl(HttpUrl url, String userId) { | ||||
|         final String davFilesPath = WEBDAV_FILES_PATH_4_0 + userId; | ||||
|         final String absoluteDavPath = Uri.decode(url.encodedPath()); | ||||
|         final String pathToOc = absoluteDavPath.split(davFilesPath)[0]; | ||||
|         return absoluteDavPath.replace(pathToOc + davFilesPath, ""); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Used internally. Reset all file properties | ||||
|      */ | ||||
| @ -260,31 +293,6 @@ public class RemoteFile implements Parcelable, Serializable { | ||||
|         mPrivateLink = null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<RemoteFile> CREATOR = new Parcelable.Creator<RemoteFile>() { | ||||
|         @Override | ||||
|         public RemoteFile createFromParcel(Parcel source) { | ||||
|             return new RemoteFile(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public RemoteFile[] newArray(int size) { | ||||
|             return new RemoteFile[size]; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected RemoteFile(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     public void readFromParcel(Parcel source) { | ||||
|         mRemotePath = source.readString(); | ||||
|         mMimeType = source.readString(); | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,20 +24,19 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.files; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.MoveMethod; | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; | ||||
| 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; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| /** | ||||
|  * Remote operation performing the rename of a remote file or folder in the ownCloud server. | ||||
| @ -73,7 +72,7 @@ public class RenameRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|         String parent = (new File(mOldRemotePath)).getParent(); | ||||
|         parent = (parent.endsWith(FileUtils.PATH_SEPARATOR)) ? parent : parent + | ||||
|             FileUtils.PATH_SEPARATOR; | ||||
|                 FileUtils.PATH_SEPARATOR; | ||||
|         mNewRemotePath = parent + mNewName; | ||||
|         if (isFolder) { | ||||
|             mNewRemotePath += FileUtils.PATH_SEPARATOR; | ||||
| @ -90,10 +89,11 @@ public class RenameRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|         final OwnCloudVersion version = client.getOwnCloudVersion(); | ||||
|         final boolean versionWithForbiddenChars = | ||||
|             (version != null && version.isVersionWithForbiddenCharacters()); | ||||
|                 (version != null && version.isVersionWithForbiddenCharacters()); | ||||
| 
 | ||||
|         if(!FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars)) | ||||
|         if (!FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars)) { | ||||
|             return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             if (mNewName.equals(mOldName)) { | ||||
| @ -134,11 +134,11 @@ public class RenameRemoteFileOperation extends RemoteOperation { | ||||
|     /** | ||||
|      * Checks if a file with the new name already exists. | ||||
|      * | ||||
|      * @return      'True' if the target path is already used by an existing file. | ||||
|      * @return 'True' if the target path is already used by an existing file. | ||||
|      */ | ||||
|     private boolean targetPathIsUsed(OwnCloudClient client) { | ||||
|         ExistenceCheckRemoteOperation existenceCheckRemoteOperation = | ||||
|             new ExistenceCheckRemoteOperation(mNewRemotePath, false, false); | ||||
|                 new ExistenceCheckRemoteOperation(mNewRemotePath, false, false); | ||||
|         RemoteOperationResult exists = existenceCheckRemoteOperation.run(client); | ||||
|         return exists.isSuccess(); | ||||
|     } | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -34,6 +34,7 @@ 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; | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.net.URL; | ||||
| @ -41,13 +42,11 @@ import java.util.HashSet; | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.atomic.AtomicBoolean; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| /** | ||||
|  * Remote operation performing the upload of a remote file to the ownCloud server. | ||||
|  *  | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  * @author masensio | ||||
|  * @author David González Verdugo | ||||
| @ -56,15 +55,13 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
| public class UploadRemoteFileOperation extends RemoteOperation { | ||||
| 
 | ||||
|     private static final String TAG = UploadRemoteFileOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); | ||||
|     protected String mLocalPath; | ||||
|     protected String mRemotePath; | ||||
|     protected String mMimeType; | ||||
|     protected String mFileLastModifTimestamp; | ||||
|     protected PutMethod mPutMethod = null; | ||||
|     protected String mRequiredEtag = null; | ||||
| 
 | ||||
|     protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false); | ||||
|     protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>(); | ||||
| 
 | ||||
|     protected FileRequestBody mFileRequestBody = null; | ||||
| @ -153,8 +150,8 @@ public class UploadRemoteFileOperation extends RemoteOperation { | ||||
|     public Set<OnDatatransferProgressListener> getDataTransferListeners() { | ||||
|         return mDataTransferListeners; | ||||
|     } | ||||
|      | ||||
|     public void addDatatransferProgressListener (OnDatatransferProgressListener listener) { | ||||
| 
 | ||||
|     public void addDatatransferProgressListener(OnDatatransferProgressListener listener) { | ||||
|         synchronized (mDataTransferListeners) { | ||||
|             mDataTransferListeners.add(listener); | ||||
|         } | ||||
| @ -162,7 +159,7 @@ public class UploadRemoteFileOperation extends RemoteOperation { | ||||
|             mFileRequestBody.addDatatransferProgressListener(listener); | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) { | ||||
|         synchronized (mDataTransferListeners) { | ||||
|             mDataTransferListeners.remove(listener); | ||||
| @ -171,12 +168,13 @@ public class UploadRemoteFileOperation extends RemoteOperation { | ||||
|             mFileRequestBody.removeDatatransferProgressListener(listener); | ||||
|         } | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     public void cancel() { | ||||
|         synchronized (mCancellationRequested) { | ||||
|             mCancellationRequested.set(true); | ||||
|             if (mPutMethod != null) | ||||
|             if (mPutMethod != null) { | ||||
|                 mPutMethod.abort(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -32,6 +32,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult; | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation; | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.RandomAccessFile; | ||||
| @ -39,8 +40,6 @@ import java.net.URL; | ||||
| import java.nio.channels.FileChannel; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| 
 | ||||
| import okhttp3.MediaType; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.HttpConstants.IF_MATCH_HEADER; | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| @ -52,8 +51,8 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  */ | ||||
| public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation { | ||||
| 
 | ||||
|     private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins. | ||||
|     public static final long CHUNK_SIZE = 1024000; | ||||
|     private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins. | ||||
|     private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     private String mTransferId; | ||||
| @ -127,11 +126,13 @@ public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (channel != null) | ||||
|         if (channel != null) { | ||||
|             channel.close(); | ||||
|         } | ||||
| 
 | ||||
|         if (raf != null) | ||||
|         if (raf != null) { | ||||
|             raf.close(); | ||||
|         } | ||||
| 
 | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -35,8 +35,8 @@ public class CreateRemoteChunkFolderOperation extends CreateRemoteFolderOperatio | ||||
|     /** | ||||
|      * 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. | ||||
|      * @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. | ||||
|      */ | ||||
|     public CreateRemoteChunkFolderOperation(String remotePath, boolean createFullPath) { | ||||
|         super(remotePath, createFullPath); | ||||
|  | ||||
| @ -35,6 +35,7 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod; | ||||
| 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 okhttp3.FormBody; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.text.DateFormat; | ||||
| @ -42,8 +43,6 @@ import java.text.SimpleDateFormat; | ||||
| import java.util.Calendar; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import okhttp3.FormBody; | ||||
| 
 | ||||
| /** | ||||
|  * Creates a new share.  This allows sharing with a user or group or as a link. | ||||
|  * | ||||
| @ -133,12 +132,11 @@ public class CreateRemoteShareOperation extends RemoteOperation { | ||||
|         mGetShareDetails = false;        // defaults to false for backwards compatibility | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set name to create in Share resource. Ignored by servers previous to version 10.0.0 | ||||
|      * | ||||
|      * @param name     Name to set to the target share. | ||||
|      *                 Null or empty string result in no value set for the name. | ||||
|      * @param name Name to set to the target share. | ||||
|      *             Null or empty string result in no value set for the name. | ||||
|      */ | ||||
|     public void setName(String name) { | ||||
|         this.mName = (name == null) ? "" : name; | ||||
| @ -154,7 +152,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { | ||||
|         mPassword = password; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set expiration date to create in Share resource. | ||||
|      * | ||||
| @ -165,7 +162,6 @@ public class CreateRemoteShareOperation extends RemoteOperation { | ||||
|         mExpirationDateInMillis = expirationDateInMillis; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set permissions to create in Share resource. | ||||
|      * | ||||
|  | ||||
| @ -50,7 +50,6 @@ public class GetRemoteShareOperation extends RemoteOperation<ShareParserResult> | ||||
| 
 | ||||
|     private long mRemoteId; | ||||
| 
 | ||||
| 
 | ||||
|     public GetRemoteShareOperation(long remoteId) { | ||||
|         mRemoteId = remoteId; | ||||
|     } | ||||
|  | ||||
| @ -36,7 +36,6 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| 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.json.JSONArray; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| @ -47,24 +46,24 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
| 
 | ||||
| /** | ||||
|  * Created by masensio on 08/10/2015. | ||||
|  * | ||||
|  * <p> | ||||
|  * Retrieves a list of sharees (possible targets of a share) from the ownCloud server. | ||||
|  * | ||||
|  * <p> | ||||
|  * Currently only handles users and groups. Users in other OC servers (federation) should be added later. | ||||
|  * | ||||
|  * <p> | ||||
|  * Depends on SHAREE API. {@See https://github.com/owncloud/documentation/issues/1626} | ||||
|  * | ||||
|  * <p> | ||||
|  * 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 | ||||
|  * | ||||
|  * 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 | ||||
|  * <p> | ||||
|  * Status codes: | ||||
|  *    100 - successful | ||||
|  * 100 - successful | ||||
|  * | ||||
|  * @author masensio | ||||
|  * @author David A. Velasco | ||||
| @ -72,22 +71,22 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  */ | ||||
| public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObject>> { | ||||
| 
 | ||||
|     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"; | ||||
|     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 = "file";         //  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"; | ||||
| @ -95,11 +94,6 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|     private static final String NODE_USERS = "users"; | ||||
|     private static final String NODE_GROUPS = "groups"; | ||||
|     private static final String NODE_REMOTES = "remotes"; | ||||
|     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"; | ||||
| 
 | ||||
|     private String mSearchString; | ||||
|     private int mPage; | ||||
|     private int mPerPage; | ||||
| @ -107,9 +101,9 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|     /** | ||||
|      * 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 | ||||
|      * @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; | ||||
| @ -121,7 +115,7 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|     protected RemoteOperationResult<ArrayList<JSONObject>> run(OwnCloudClient client) { | ||||
|         RemoteOperationResult<ArrayList<JSONObject>> result; | ||||
| 
 | ||||
|         try{ | ||||
|         try { | ||||
|             Uri requestUri = client.getBaseUri(); | ||||
|             Uri.Builder uriBuilder = requestUri.buildUpon() | ||||
|                     .appendEncodedPath(OCS_ROUTE) | ||||
| @ -138,7 +132,7 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|             int status = client.executeHttpMethod(getMethod); | ||||
|             String response = getMethod.getResponseBodyAsString(); | ||||
| 
 | ||||
|             if(isSuccess(status)) { | ||||
|             if (isSuccess(status)) { | ||||
|                 Log_OC.d(TAG, "Successful response: " + response); | ||||
| 
 | ||||
|                 // Parse the response | ||||
| @ -162,8 +156,8 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|                 }; | ||||
| 
 | ||||
|                 ArrayList<JSONObject> data = new ArrayList<>(); // For result data | ||||
|                 for (int i=0; i<6; i++) { | ||||
|                     for(int j=0; j< jsonResults[i].length(); j++){ | ||||
|                 for (int i = 0; i < 6; 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)); | ||||
| @ -173,7 +167,7 @@ public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObj | ||||
|                 result = new RemoteOperationResult<>(OK); | ||||
|                 result.setData(data); | ||||
| 
 | ||||
|                 Log_OC.d(TAG, "*** Get Users or groups completed " ); | ||||
|                 Log_OC.d(TAG, "*** Get Users or groups completed "); | ||||
| 
 | ||||
|             } else { | ||||
|                 result = new RemoteOperationResult<>(getMethod); | ||||
|  | ||||
| @ -98,7 +98,7 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation<ShareParser | ||||
|             if (isSuccess(status)) { | ||||
|                 // Parse xml response and obtain the list of shares | ||||
|                 ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( | ||||
|                     new ShareXMLParser() | ||||
|                         new ShareXMLParser() | ||||
|                 ); | ||||
|                 parser.setOwnCloudVersion(client.getOwnCloudVersion()); | ||||
|                 parser.setServerBaseUri(client.getBaseUri()); | ||||
|  | ||||
| @ -69,7 +69,7 @@ public class GetRemoteSharesOperation extends RemoteOperation { | ||||
| 
 | ||||
|                 // Parse xml response and obtain the list of shares | ||||
|                 ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser( | ||||
|                     new ShareXMLParser() | ||||
|                         new ShareXMLParser() | ||||
|                 ); | ||||
|                 parser.setOwnCloudVersion(client.getOwnCloudVersion()); | ||||
|                 parser.setServerBaseUri(client.getBaseUri()); | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2017 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,15 +24,13 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.shares; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| import android.os.Parcel; | ||||
| import android.os.Parcelable; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| 
 | ||||
| import java.io.Serializable; | ||||
| 
 | ||||
| /** | ||||
|  * Contains the data of a Share from the Share API | ||||
| @ -42,13 +40,6 @@ import com.owncloud.android.lib.resources.files.FileUtils; | ||||
|  */ | ||||
| public class OCShare implements Parcelable, Serializable { | ||||
| 
 | ||||
|     /** | ||||
|      * Generated - should be refreshed every time the class changes!! | ||||
|      */ | ||||
|     private static final long serialVersionUID = 4124975224281327921L; | ||||
| 
 | ||||
|     private static final String TAG = OCShare.class.getSimpleName(); | ||||
| 
 | ||||
|     public static final int DEFAULT_PERMISSION = -1; | ||||
|     public static final int READ_PERMISSION_FLAG = 1; | ||||
|     public static final int UPDATE_PERMISSION_FLAG = 2; | ||||
| @ -56,29 +47,47 @@ public class OCShare implements Parcelable, Serializable { | ||||
|     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; | ||||
|             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; | ||||
|             MAXIMUM_PERMISSIONS_FOR_FILE + | ||||
|                     CREATE_PERMISSION_FLAG + | ||||
|                     DELETE_PERMISSION_FLAG; | ||||
|     public static final int FEDERATED_PERMISSIONS_FOR_FILE_UP_TO_OC9 = | ||||
|         READ_PERMISSION_FLAG + | ||||
|             UPDATE_PERMISSION_FLAG; | ||||
|             READ_PERMISSION_FLAG + | ||||
|                     UPDATE_PERMISSION_FLAG; | ||||
|     public static final int FEDERATED_PERMISSIONS_FOR_FILE_AFTER_OC9 = | ||||
|         READ_PERMISSION_FLAG + | ||||
|             UPDATE_PERMISSION_FLAG + | ||||
|             SHARE_PERMISSION_FLAG; | ||||
|             READ_PERMISSION_FLAG + | ||||
|                     UPDATE_PERMISSION_FLAG + | ||||
|                     SHARE_PERMISSION_FLAG; | ||||
|     public static final int FEDERATED_PERMISSIONS_FOR_FOLDER_UP_TO_OC9 = | ||||
|         READ_PERMISSION_FLAG + | ||||
|             UPDATE_PERMISSION_FLAG + | ||||
|             CREATE_PERMISSION_FLAG + | ||||
|             DELETE_PERMISSION_FLAG; | ||||
|             READ_PERMISSION_FLAG + | ||||
|                     UPDATE_PERMISSION_FLAG + | ||||
|                     CREATE_PERMISSION_FLAG + | ||||
|                     DELETE_PERMISSION_FLAG; | ||||
|     public static final int FEDERATED_PERMISSIONS_FOR_FOLDER_AFTER_OC9 = | ||||
|         FEDERATED_PERMISSIONS_FOR_FOLDER_UP_TO_OC9 + | ||||
|             SHARE_PERMISSION_FLAG; | ||||
|             FEDERATED_PERMISSIONS_FOR_FOLDER_UP_TO_OC9 + | ||||
|                     SHARE_PERMISSION_FLAG; | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<OCShare> CREATOR = new Parcelable.Creator<OCShare>() { | ||||
|         @Override | ||||
|         public OCShare createFromParcel(Parcel source) { | ||||
|             return new OCShare(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public OCShare[] newArray(int size) { | ||||
|             return new OCShare[size]; | ||||
|         } | ||||
|     }; | ||||
|     /** | ||||
|      * Generated - should be refreshed every time the class changes!! | ||||
|      */ | ||||
|     private static final long serialVersionUID = 4124975224281327921L; | ||||
|     private static final String TAG = OCShare.class.getSimpleName(); | ||||
|     private long mId; | ||||
|     private long mFileSource; | ||||
|     private long mItemSource; | ||||
| @ -110,6 +119,17 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         mPath = path; | ||||
|     } | ||||
| 
 | ||||
|     /// Getters and Setters | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected OCShare(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Used internally. Reset all file properties | ||||
|      */ | ||||
| @ -132,8 +152,6 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         mName = ""; | ||||
|     } | ||||
| 
 | ||||
|     /// Getters and Setters | ||||
| 
 | ||||
|     public long getId() { | ||||
|         return mId; | ||||
|     } | ||||
| @ -266,30 +284,6 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         return ShareType.PUBLIC_LINK.equals(mShareType) && mShareWith.length() > 0; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parcelable Methods | ||||
|      */ | ||||
|     public static final Parcelable.Creator<OCShare> CREATOR = new Parcelable.Creator<OCShare>() { | ||||
|         @Override | ||||
|         public OCShare createFromParcel(Parcel source) { | ||||
|             return new OCShare(source); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public OCShare[] newArray(int size) { | ||||
|             return new OCShare[size]; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     /** | ||||
|      * Reconstruct from parcel | ||||
|      * | ||||
|      * @param source The source parcel | ||||
|      */ | ||||
|     protected OCShare(Parcel source) { | ||||
|         readFromParcel(source); | ||||
|     } | ||||
| 
 | ||||
|     public void readFromParcel(Parcel source) { | ||||
|         mId = source.readLong(); | ||||
| 
 | ||||
| @ -314,13 +308,11 @@ public class OCShare implements Parcelable, Serializable { | ||||
|         mName = source.readString(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public int describeContents() { | ||||
|         return this.hashCode(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void writeToParcel(Parcel dest, int flags) { | ||||
|         dest.writeLong(mId); | ||||
|  | ||||
| @ -25,21 +25,22 @@ | ||||
| 
 | ||||
| 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 */ | ||||
|     /** | ||||
|      * 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 | ||||
|      * @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); | ||||
| @ -49,8 +50,8 @@ public class SharePermissionsBuilder { | ||||
|     /** | ||||
|      * 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 | ||||
|      * @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); | ||||
| @ -60,8 +61,8 @@ public class SharePermissionsBuilder { | ||||
|     /** | ||||
|      * 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 | ||||
|      * @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); | ||||
| @ -71,8 +72,8 @@ public class SharePermissionsBuilder { | ||||
|     /** | ||||
|      * 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 | ||||
|      * @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); | ||||
| @ -82,8 +83,8 @@ public class SharePermissionsBuilder { | ||||
|     /** | ||||
|      * 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. | ||||
|      * @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) { | ||||
| @ -98,7 +99,7 @@ public class SharePermissionsBuilder { | ||||
|     /** | ||||
|      * 'Builds' the int value for the accumulated set of permissions. | ||||
|      * | ||||
|      * @return  An int value representing the accumulated set of permissions. | ||||
|      * @return An int value representing the accumulated set of permissions. | ||||
|      */ | ||||
|     public int build() { | ||||
|         return mPermissions; | ||||
|  | ||||
| @ -32,7 +32,6 @@ 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; | ||||
| @ -50,7 +49,6 @@ public class ShareToRemoteOperationResultParser { | ||||
|     private OwnCloudVersion mOwnCloudVersion = null; | ||||
|     private Uri mServerBaseUri = null; | ||||
| 
 | ||||
| 
 | ||||
|     public ShareToRemoteOperationResultParser(ShareXMLParser shareXmlParser) { | ||||
|         mShareXmlParser = shareXmlParser; | ||||
|     } | ||||
| @ -94,7 +92,7 @@ public class ShareToRemoteOperationResultParser { | ||||
|                             // (needed for OC servers < 9.0.0, see ShareXMLParser.java#line256) | ||||
|                             if (share.getShareType() == ShareType.PUBLIC_LINK | ||||
|                                     && (share.getShareLink() == null | ||||
|                                         || share.getShareLink().length() <= 0) | ||||
|                                     || share.getShareLink().length() <= 0) | ||||
|                                     && share.getToken().length() > 0) { | ||||
|                                 if (mServerBaseUri != null) { | ||||
|                                     String sharingLinkPath = ShareUtils.getSharingLinkPath(mOwnCloudVersion); | ||||
| @ -112,11 +110,11 @@ public class ShareToRemoteOperationResultParser { | ||||
|                     Log_OC.e(TAG, "Successful status with no share in the response"); | ||||
|                 } | ||||
| 
 | ||||
|             } else if (mShareXmlParser.isWrongParameter()){ | ||||
|             } else if (mShareXmlParser.isWrongParameter()) { | ||||
|                 result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER); | ||||
|                 result.setData(new ShareParserResult(null, mShareXmlParser.getMessage())); | ||||
| 
 | ||||
|             } else if (mShareXmlParser.isNotFound()){ | ||||
|             } else if (mShareXmlParser.isNotFound()) { | ||||
|                 result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND); | ||||
|                 result.setData(new ShareParserResult(null, mShareXmlParser.getMessage())); | ||||
| 
 | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -27,55 +27,51 @@ package com.owncloud.android.lib.resources.shares; | ||||
| /** | ||||
|  * Enum for Share Type, with values: | ||||
|  * -1 - No shared | ||||
|  *  0 - Shared by user | ||||
|  *  1 - Shared by group | ||||
|  *  3 - Shared by public link | ||||
|  *  4 - Shared by e-mail | ||||
|  *  5 - Shared by contact | ||||
|  *   | ||||
|  * @author masensio | ||||
|  * 0 - Shared by user | ||||
|  * 1 - Shared by group | ||||
|  * 3 - Shared by public link | ||||
|  * 4 - Shared by e-mail | ||||
|  * 5 - Shared by contact | ||||
|  * | ||||
|  * @author masensio | ||||
|  */ | ||||
| 
 | ||||
| public enum ShareType { | ||||
|     NO_SHARED (-1), | ||||
|     USER (0), | ||||
|     GROUP (1), | ||||
|     PUBLIC_LINK (3), | ||||
|     EMAIL (4), | ||||
|     CONTACT (5), | ||||
|     FEDERATED (6); | ||||
|      | ||||
|     NO_SHARED(-1), | ||||
|     USER(0), | ||||
|     GROUP(1), | ||||
|     PUBLIC_LINK(3), | ||||
|     EMAIL(4), | ||||
|     CONTACT(5), | ||||
|     FEDERATED(6); | ||||
| 
 | ||||
|     private int value; | ||||
|      | ||||
|     private ShareType(int value) | ||||
|     { | ||||
| 
 | ||||
|     private ShareType(int value) { | ||||
|         this.value = value; | ||||
|     } | ||||
|      | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
|      | ||||
|     public static ShareType fromValue(int value) | ||||
|     { | ||||
|         switch (value) | ||||
|         { | ||||
|         case -1: | ||||
|             return NO_SHARED; | ||||
|         case 0: | ||||
|             return USER; | ||||
|         case 1: | ||||
|             return GROUP; | ||||
|         case 3: | ||||
|             return PUBLIC_LINK; | ||||
|         case 4: | ||||
|             return EMAIL; | ||||
|         case 5: | ||||
|             return CONTACT; | ||||
|         case 6: | ||||
|             return FEDERATED; | ||||
| 
 | ||||
|     public static ShareType fromValue(int value) { | ||||
|         switch (value) { | ||||
|             case -1: | ||||
|                 return NO_SHARED; | ||||
|             case 0: | ||||
|                 return USER; | ||||
|             case 1: | ||||
|                 return GROUP; | ||||
|             case 3: | ||||
|                 return PUBLIC_LINK; | ||||
|             case 4: | ||||
|                 return EMAIL; | ||||
|             case 5: | ||||
|                 return CONTACT; | ||||
|             case 6: | ||||
|                 return FEDERATED; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| }; | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -28,23 +28,22 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion; | ||||
| 
 | ||||
| /** | ||||
|  * Contains Constants for Share Operation | ||||
|  *  | ||||
|  * | ||||
|  * @author masensio | ||||
|  * @author David González Verdugo | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| public class ShareUtils { | ||||
| 
 | ||||
| 	// OCS Route | ||||
| 	public static final String SHARING_API_PATH ="ocs/v2.php/apps/files_sharing/api/v1/shares"; | ||||
|     // OCS Route | ||||
|     public static final String SHARING_API_PATH = "ocs/v2.php/apps/files_sharing/api/v1/shares"; | ||||
| 
 | ||||
|     // 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()){ | ||||
|     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; | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -24,417 +24,425 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.shares; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| import org.xmlpull.v1.XmlPullParser; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| import org.xmlpull.v1.XmlPullParserFactory; | ||||
| 
 | ||||
| //import android.util.Log; | ||||
| import android.util.Xml; | ||||
| 
 | ||||
| import com.owncloud.android.lib.common.network.WebdavUtils; | ||||
| import com.owncloud.android.lib.resources.files.FileUtils; | ||||
| import org.xmlpull.v1.XmlPullParser; | ||||
| import org.xmlpull.v1.XmlPullParserException; | ||||
| import org.xmlpull.v1.XmlPullParserFactory; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| //import android.util.Log; | ||||
| 
 | ||||
| /** | ||||
|  * Parser for Share API Response | ||||
|  * | ||||
|  * @author masensio | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| 
 | ||||
| public class ShareXMLParser { | ||||
| 
 | ||||
| 	//private static final String TAG = ShareXMLParser.class.getSimpleName(); | ||||
|     //private static final String TAG = ShareXMLParser.class.getSimpleName(); | ||||
| 
 | ||||
| 	// No namespaces | ||||
| 	private static final String ns = null; | ||||
|     // No namespaces | ||||
|     private static final String ns = null; | ||||
| 
 | ||||
| 	// NODES for XML Parser | ||||
| 	private static final String NODE_OCS = "ocs"; | ||||
|     // NODES for XML Parser | ||||
|     private static final String NODE_OCS = "ocs"; | ||||
| 
 | ||||
| 	private static final String NODE_META = "meta"; | ||||
| 	private static final String NODE_STATUS = "status"; | ||||
| 	private static final String NODE_STATUS_CODE = "statuscode"; | ||||
| 	private static final String NODE_MESSAGE = "message"; | ||||
|     private static final String NODE_META = "meta"; | ||||
|     private static final String NODE_STATUS = "status"; | ||||
|     private static final String NODE_STATUS_CODE = "statuscode"; | ||||
|     private static final String NODE_MESSAGE = "message"; | ||||
| 
 | ||||
| 	private static final String NODE_DATA = "data"; | ||||
| 	private static final String NODE_ELEMENT = "element"; | ||||
| 	private static final String NODE_ID = "id"; | ||||
| 	private static final String NODE_ITEM_TYPE = "item_type"; | ||||
| 	private static final String NODE_ITEM_SOURCE = "item_source"; | ||||
| 	private static final String NODE_PARENT = "parent"; | ||||
| 	private static final String NODE_SHARE_TYPE = "share_type"; | ||||
| 	private static final String NODE_SHARE_WITH = "share_with"; | ||||
| 	private static final String NODE_FILE_SOURCE = "file_source"; | ||||
| 	private static final String NODE_PATH = "path"; | ||||
| 	private static final String NODE_PERMISSIONS = "permissions"; | ||||
| 	private static final String NODE_STIME = "stime"; | ||||
| 	private static final String NODE_EXPIRATION = "expiration"; | ||||
| 	private static final String NODE_TOKEN = "token"; | ||||
| 	private static final String NODE_STORAGE = "storage"; | ||||
| 	private static final String NODE_MAIL_SEND = "mail_send"; | ||||
| 	private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_displayname"; | ||||
|     private static final String NODE_DATA = "data"; | ||||
|     private static final String NODE_ELEMENT = "element"; | ||||
|     private static final String NODE_ID = "id"; | ||||
|     private static final String NODE_ITEM_TYPE = "item_type"; | ||||
|     private static final String NODE_ITEM_SOURCE = "item_source"; | ||||
|     private static final String NODE_PARENT = "parent"; | ||||
|     private static final String NODE_SHARE_TYPE = "share_type"; | ||||
|     private static final String NODE_SHARE_WITH = "share_with"; | ||||
|     private static final String NODE_FILE_SOURCE = "file_source"; | ||||
|     private static final String NODE_PATH = "path"; | ||||
|     private static final String NODE_PERMISSIONS = "permissions"; | ||||
|     private static final String NODE_STIME = "stime"; | ||||
|     private static final String NODE_EXPIRATION = "expiration"; | ||||
|     private static final String NODE_TOKEN = "token"; | ||||
|     private static final String NODE_STORAGE = "storage"; | ||||
|     private static final String NODE_MAIL_SEND = "mail_send"; | ||||
|     private static final String NODE_SHARE_WITH_DISPLAY_NAME = "share_with_displayname"; | ||||
|     private static final String NODE_NAME = "name"; | ||||
| 	 | ||||
| 	private static final String NODE_URL = "url"; | ||||
| 
 | ||||
| 	private static final String TYPE_FOLDER = "folder"; | ||||
| 	 | ||||
| 	private static final int SUCCESS = 200; | ||||
| 	private static final int ERROR_WRONG_PARAMETER = 400; | ||||
| 	private static final int ERROR_FORBIDDEN = 403; | ||||
| 	private static final int ERROR_NOT_FOUND = 404; | ||||
|     private static final String NODE_URL = "url"; | ||||
| 
 | ||||
| 	private String mStatus; | ||||
| 	private int mStatusCode; | ||||
| 	private String mMessage; | ||||
|     private static final String TYPE_FOLDER = "folder"; | ||||
| 
 | ||||
| 	// Getters and Setters | ||||
| 	public String getStatus() { | ||||
| 		return mStatus; | ||||
| 	} | ||||
|     private static final int SUCCESS = 200; | ||||
|     private static final int ERROR_WRONG_PARAMETER = 400; | ||||
|     private static final int ERROR_FORBIDDEN = 403; | ||||
|     private static final int ERROR_NOT_FOUND = 404; | ||||
| 
 | ||||
| 	public void setStatus(String status) { | ||||
| 		this.mStatus = status; | ||||
| 	} | ||||
|     private String mStatus; | ||||
|     private int mStatusCode; | ||||
|     private String mMessage; | ||||
| 
 | ||||
| 	public int getStatusCode() { | ||||
| 		return mStatusCode; | ||||
| 	} | ||||
|     // Constructor | ||||
|     public ShareXMLParser() { | ||||
|         mStatusCode = -1; | ||||
|     } | ||||
| 
 | ||||
| 	public void setStatusCode(int statusCode) { | ||||
| 		this.mStatusCode = statusCode; | ||||
| 	} | ||||
|     // Getters and Setters | ||||
|     public String getStatus() { | ||||
|         return mStatus; | ||||
|     } | ||||
| 
 | ||||
| 	public String getMessage() { | ||||
| 		return mMessage; | ||||
| 	} | ||||
|     public void setStatus(String status) { | ||||
|         this.mStatus = status; | ||||
|     } | ||||
| 
 | ||||
| 	public void setMessage(String message) { | ||||
| 		this.mMessage = message; | ||||
| 	} | ||||
|     public int getStatusCode() { | ||||
|         return mStatusCode; | ||||
|     } | ||||
| 
 | ||||
| 	// Constructor | ||||
| 	public ShareXMLParser() { | ||||
| 		mStatusCode = -1; | ||||
| 	} | ||||
|     public void setStatusCode(int statusCode) { | ||||
|         this.mStatusCode = statusCode; | ||||
|     } | ||||
| 
 | ||||
| 	public boolean isSuccess() { | ||||
| 		return mStatusCode == SUCCESS; | ||||
| 	} | ||||
|     public String getMessage() { | ||||
|         return mMessage; | ||||
|     } | ||||
| 
 | ||||
| 	public boolean isForbidden() { | ||||
| 		return mStatusCode == ERROR_FORBIDDEN; | ||||
| 	} | ||||
|     public void setMessage(String message) { | ||||
|         this.mMessage = message; | ||||
|     } | ||||
| 
 | ||||
| 	public boolean isNotFound() { | ||||
| 		return mStatusCode == ERROR_NOT_FOUND; | ||||
| 	} | ||||
|     public boolean isSuccess() { | ||||
|         return mStatusCode == SUCCESS; | ||||
|     } | ||||
| 
 | ||||
| 	public boolean isWrongParameter() { | ||||
| 		return mStatusCode == ERROR_WRONG_PARAMETER; | ||||
| 	} | ||||
|     public boolean isForbidden() { | ||||
|         return mStatusCode == ERROR_FORBIDDEN; | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse is as response of Share API | ||||
| 	 * @param is | ||||
| 	 * @return List of ShareRemoteFiles | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException, | ||||
| 			IOException { | ||||
|     public boolean isNotFound() { | ||||
|         return mStatusCode == ERROR_NOT_FOUND; | ||||
|     } | ||||
| 
 | ||||
| 		try { | ||||
| 			// XMLPullParser | ||||
| 			XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); | ||||
| 			factory.setNamespaceAware(true); | ||||
|     public boolean isWrongParameter() { | ||||
|         return mStatusCode == ERROR_WRONG_PARAMETER; | ||||
|     } | ||||
| 
 | ||||
| 			XmlPullParser parser = Xml.newPullParser(); | ||||
| 			parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); | ||||
| 			parser.setInput(is, null); | ||||
| 			parser.nextTag(); | ||||
| 			return readOCS(parser); | ||||
|     /** | ||||
|      * Parse is as response of Share API | ||||
|      * | ||||
|      * @param is | ||||
|      * @return List of ShareRemoteFiles | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     public ArrayList<OCShare> parseXMLResponse(InputStream is) throws XmlPullParserException, | ||||
|             IOException { | ||||
| 
 | ||||
| 		} finally { | ||||
| 			is.close(); | ||||
| 		} | ||||
| 	} | ||||
|         try { | ||||
|             // XMLPullParser | ||||
|             XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); | ||||
|             factory.setNamespaceAware(true); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse OCS node | ||||
| 	 * @param parser | ||||
| 	 * @return List of ShareRemoteFiles | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException, | ||||
| 			IOException { | ||||
| 		ArrayList<OCShare> shares = new ArrayList<>(); | ||||
| 		parser.require(XmlPullParser.START_TAG,  ns , NODE_OCS); | ||||
| 		while (parser.next() != XmlPullParser.END_TAG) { | ||||
| 			if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			String name = parser.getName(); | ||||
| 			// read NODE_META and NODE_DATA | ||||
| 			if (name.equalsIgnoreCase(NODE_META)) { | ||||
| 				readMeta(parser); | ||||
| 			} else if (name.equalsIgnoreCase(NODE_DATA)) { | ||||
| 				shares = readData(parser); | ||||
| 			} else { | ||||
| 				skip(parser); | ||||
| 			} | ||||
|             XmlPullParser parser = Xml.newPullParser(); | ||||
|             parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); | ||||
|             parser.setInput(is, null); | ||||
|             parser.nextTag(); | ||||
|             return readOCS(parser); | ||||
| 
 | ||||
| 		} | ||||
| 		return shares; | ||||
| 	} | ||||
|         } finally { | ||||
|             is.close(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse Meta node | ||||
| 	 * @param parser | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	private void readMeta(XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
| 		parser.require(XmlPullParser.START_TAG, ns, NODE_META); | ||||
| 		//Log_OC.d(TAG, "---- NODE META ---"); | ||||
| 		while (parser.next() != XmlPullParser.END_TAG) { | ||||
| 			if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			String name = parser.getName(); | ||||
|     /** | ||||
|      * Parse OCS node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return List of ShareRemoteFiles | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private ArrayList<OCShare> readOCS(XmlPullParser parser) throws XmlPullParserException, | ||||
|             IOException { | ||||
|         ArrayList<OCShare> shares = new ArrayList<>(); | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_OCS); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
|             } | ||||
|             String name = parser.getName(); | ||||
|             // read NODE_META and NODE_DATA | ||||
|             if (name.equalsIgnoreCase(NODE_META)) { | ||||
|                 readMeta(parser); | ||||
|             } else if (name.equalsIgnoreCase(NODE_DATA)) { | ||||
|                 shares = readData(parser); | ||||
|             } else { | ||||
|                 skip(parser); | ||||
|             } | ||||
| 
 | ||||
| 			if  (name.equalsIgnoreCase(NODE_STATUS)) { | ||||
| 				setStatus(readNode(parser, NODE_STATUS)); | ||||
|         } | ||||
|         return shares; | ||||
|     } | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_STATUS_CODE)) { | ||||
| 				setStatusCode(Integer.parseInt(readNode(parser, NODE_STATUS_CODE))); | ||||
|     /** | ||||
|      * Parse Meta node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private void readMeta(XmlPullParser parser) throws XmlPullParserException, IOException { | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_META); | ||||
|         //Log_OC.d(TAG, "---- NODE META ---"); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
|             } | ||||
|             String name = parser.getName(); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_MESSAGE)) { | ||||
| 				setMessage(readNode(parser, NODE_MESSAGE)); | ||||
|             if (name.equalsIgnoreCase(NODE_STATUS)) { | ||||
|                 setStatus(readNode(parser, NODE_STATUS)); | ||||
| 
 | ||||
| 			} else { | ||||
| 				skip(parser); | ||||
| 			} | ||||
|             } 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)); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse Data node | ||||
| 	 * @param parser | ||||
| 	 * @return | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException, | ||||
| 			IOException { | ||||
| 		ArrayList<OCShare> shares = new ArrayList<OCShare>(); | ||||
| 		OCShare share = null; | ||||
|             } else { | ||||
|                 skip(parser); | ||||
|             } | ||||
| 
 | ||||
| 		parser.require(XmlPullParser.START_TAG, ns, NODE_DATA);		 | ||||
| 		//Log_OC.d(TAG, "---- NODE DATA ---"); | ||||
| 		while (parser.next() != XmlPullParser.END_TAG) { | ||||
| 			if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
| 				continue; | ||||
| 			} | ||||
| 			String name = parser.getName(); | ||||
| 			if (name.equalsIgnoreCase(NODE_ELEMENT)) { | ||||
| 				readElement(parser, shares); | ||||
| 				 | ||||
| 			}  else if (name.equalsIgnoreCase(NODE_ID)) {// Parse Create XML Response | ||||
| 				share = new OCShare(); | ||||
| 				String value = readNode(parser, NODE_ID); | ||||
| 				share.setIdRemoteShared(Integer.parseInt(value)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_URL)) { | ||||
| 				// NOTE: this field is received in all the public shares from OC 9.0.0 | ||||
| 				// in previous versions, it's received in the result of POST requests, but not | ||||
| 				// in GET requests | ||||
| 				share.setShareType(ShareType.PUBLIC_LINK); | ||||
| 				String value = readNode(parser, NODE_URL); | ||||
| 				share.setShareLink(value); | ||||
|     /** | ||||
|      * Parse Data node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private ArrayList<OCShare> readData(XmlPullParser parser) throws XmlPullParserException, | ||||
|             IOException { | ||||
|         ArrayList<OCShare> shares = new ArrayList<OCShare>(); | ||||
|         OCShare share = null; | ||||
| 
 | ||||
| 			}  else if (name.equalsIgnoreCase(NODE_TOKEN)) { | ||||
| 				share.setToken(readNode(parser, NODE_TOKEN)); | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_DATA); | ||||
|         //Log_OC.d(TAG, "---- NODE DATA ---"); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
|             } | ||||
|             String name = parser.getName(); | ||||
|             if (name.equalsIgnoreCase(NODE_ELEMENT)) { | ||||
|                 readElement(parser, shares); | ||||
| 
 | ||||
| 			} else { | ||||
| 				skip(parser); | ||||
| 				 | ||||
| 			}  | ||||
| 		} | ||||
| 		 | ||||
| 		if (share != null) { | ||||
| 			// this is the response of a request for creation; don't pass to isValidShare() | ||||
| 			shares.add(share); | ||||
| 		} | ||||
|             } else if (name.equalsIgnoreCase(NODE_ID)) {// Parse Create XML Response | ||||
|                 share = new OCShare(); | ||||
|                 String value = readNode(parser, NODE_ID); | ||||
|                 share.setIdRemoteShared(Integer.parseInt(value)); | ||||
| 
 | ||||
| 		return shares; | ||||
|             } else if (name.equalsIgnoreCase(NODE_URL)) { | ||||
|                 // NOTE: this field is received in all the public shares from OC 9.0.0 | ||||
|                 // in previous versions, it's received in the result of POST requests, but not | ||||
|                 // in GET requests | ||||
|                 share.setShareType(ShareType.PUBLIC_LINK); | ||||
|                 String value = readNode(parser, NODE_URL); | ||||
|                 share.setShareLink(value); | ||||
| 
 | ||||
| 	} | ||||
|             } else if (name.equalsIgnoreCase(NODE_TOKEN)) { | ||||
|                 share.setToken(readNode(parser, NODE_TOKEN)); | ||||
| 
 | ||||
|             } else { | ||||
|                 skip(parser); | ||||
| 
 | ||||
| 	/**  | ||||
| 	 * Parse Element node | ||||
| 	 * @param parser | ||||
| 	 * @return | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	private void readElement(XmlPullParser parser, ArrayList<OCShare> shares) | ||||
| 			throws XmlPullParserException, IOException { | ||||
| 		parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT); | ||||
| 		 | ||||
| 		OCShare share = new OCShare(); | ||||
| 		 | ||||
| 		//Log_OC.d(TAG, "---- NODE ELEMENT ---"); | ||||
| 		while (parser.next() != XmlPullParser.END_TAG) { | ||||
| 			if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
| 	            continue; | ||||
| 	        } | ||||
| 			 | ||||
| 			String name = parser.getName(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 			if (name.equalsIgnoreCase(NODE_ELEMENT)) { | ||||
| 				// 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); | ||||
|         if (share != null) { | ||||
|             // this is the response of a request for creation; don't pass to isValidShare() | ||||
|             shares.add(share); | ||||
|         } | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_ID)) { | ||||
| 				share.setIdRemoteShared(Integer.parseInt(readNode(parser, NODE_ID))); | ||||
|         return shares; | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_ITEM_TYPE)) { | ||||
| 				share.setIsFolder(readNode(parser, NODE_ITEM_TYPE).equalsIgnoreCase(TYPE_FOLDER)); | ||||
| 				fixPathForFolder(share); | ||||
|     } | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_ITEM_SOURCE)) { | ||||
| 				share.setItemSource(Long.parseLong(readNode(parser, NODE_ITEM_SOURCE))); | ||||
|     /** | ||||
|      * Parse Element node | ||||
|      * | ||||
|      * @param parser | ||||
|      * @return | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private void readElement(XmlPullParser parser, ArrayList<OCShare> shares) | ||||
|             throws XmlPullParserException, IOException { | ||||
|         parser.require(XmlPullParser.START_TAG, ns, NODE_ELEMENT); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_PARENT)) { | ||||
| 				readNode(parser, NODE_PARENT); | ||||
|         OCShare share = new OCShare(); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_SHARE_TYPE)) { | ||||
| 				int value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE)); | ||||
| 				share.setShareType(ShareType.fromValue(value)); | ||||
|         //Log_OC.d(TAG, "---- NODE ELEMENT ---"); | ||||
|         while (parser.next() != XmlPullParser.END_TAG) { | ||||
|             if (parser.getEventType() != XmlPullParser.START_TAG) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_SHARE_WITH)) { | ||||
| 				share.setShareWith(readNode(parser, NODE_SHARE_WITH)); | ||||
|             String name = parser.getName(); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_FILE_SOURCE)) { | ||||
| 				share.setFileSource(Long.parseLong(readNode(parser, NODE_FILE_SOURCE))); | ||||
|             if (name.equalsIgnoreCase(NODE_ELEMENT)) { | ||||
|                 // 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); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_PATH)) { | ||||
| 				share.setPath(readNode(parser, NODE_PATH)); | ||||
| 				fixPathForFolder(share); | ||||
|             } else if (name.equalsIgnoreCase(NODE_ID)) { | ||||
|                 share.setIdRemoteShared(Integer.parseInt(readNode(parser, NODE_ID))); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_PERMISSIONS)) { | ||||
| 				share.setPermissions(Integer.parseInt(readNode(parser, NODE_PERMISSIONS))); | ||||
|             } else if (name.equalsIgnoreCase(NODE_ITEM_TYPE)) { | ||||
|                 share.setIsFolder(readNode(parser, NODE_ITEM_TYPE).equalsIgnoreCase(TYPE_FOLDER)); | ||||
|                 fixPathForFolder(share); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_STIME)) { | ||||
| 				share.setSharedDate(Long.parseLong(readNode(parser, NODE_STIME))); | ||||
|             } else if (name.equalsIgnoreCase(NODE_ITEM_SOURCE)) { | ||||
|                 share.setItemSource(Long.parseLong(readNode(parser, NODE_ITEM_SOURCE))); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_EXPIRATION)) { | ||||
| 				String value = readNode(parser, NODE_EXPIRATION); | ||||
| 				if (!(value.length() == 0)) { | ||||
| 					share.setExpirationDate(WebdavUtils.parseResponseDate(value).getTime());  | ||||
| 				} | ||||
|             } else if (name.equalsIgnoreCase(NODE_PARENT)) { | ||||
|                 readNode(parser, NODE_PARENT); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_TOKEN)) { | ||||
| 				share.setToken(readNode(parser, NODE_TOKEN)); | ||||
|             } else if (name.equalsIgnoreCase(NODE_SHARE_TYPE)) { | ||||
|                 int value = Integer.parseInt(readNode(parser, NODE_SHARE_TYPE)); | ||||
|                 share.setShareType(ShareType.fromValue(value)); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_STORAGE)) { | ||||
| 				readNode(parser, NODE_STORAGE); | ||||
| 			} else if (name.equalsIgnoreCase(NODE_MAIL_SEND)) { | ||||
| 				readNode(parser, NODE_MAIL_SEND); | ||||
|             } else if (name.equalsIgnoreCase(NODE_SHARE_WITH)) { | ||||
|                 share.setShareWith(readNode(parser, NODE_SHARE_WITH)); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) { | ||||
| 				share.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME)); | ||||
|             } else if (name.equalsIgnoreCase(NODE_FILE_SOURCE)) { | ||||
|                 share.setFileSource(Long.parseLong(readNode(parser, NODE_FILE_SOURCE))); | ||||
| 
 | ||||
| 			} else if (name.equalsIgnoreCase(NODE_URL)) { | ||||
| 				String value = readNode(parser, NODE_URL); | ||||
| 				share.setShareLink(value); | ||||
|             } else if (name.equalsIgnoreCase(NODE_PATH)) { | ||||
|                 share.setPath(readNode(parser, NODE_PATH)); | ||||
|                 fixPathForFolder(share); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_PERMISSIONS)) { | ||||
|                 share.setPermissions(Integer.parseInt(readNode(parser, NODE_PERMISSIONS))); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_STIME)) { | ||||
|                 share.setSharedDate(Long.parseLong(readNode(parser, NODE_STIME))); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_EXPIRATION)) { | ||||
|                 String value = readNode(parser, NODE_EXPIRATION); | ||||
|                 if (!(value.length() == 0)) { | ||||
|                     share.setExpirationDate(WebdavUtils.parseResponseDate(value).getTime()); | ||||
|                 } | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_TOKEN)) { | ||||
|                 share.setToken(readNode(parser, NODE_TOKEN)); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_STORAGE)) { | ||||
|                 readNode(parser, NODE_STORAGE); | ||||
|             } else if (name.equalsIgnoreCase(NODE_MAIL_SEND)) { | ||||
|                 readNode(parser, NODE_MAIL_SEND); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_SHARE_WITH_DISPLAY_NAME)) { | ||||
|                 share.setSharedWithDisplayName(readNode(parser, NODE_SHARE_WITH_DISPLAY_NAME)); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_URL)) { | ||||
|                 String value = readNode(parser, NODE_URL); | ||||
|                 share.setShareLink(value); | ||||
| 
 | ||||
|             } else if (name.equalsIgnoreCase(NODE_NAME)) { | ||||
|                 share.setName(readNode(parser, NODE_NAME)); | ||||
| 
 | ||||
|             } else { | ||||
| 				skip(parser); | ||||
| 			}  | ||||
| 		}		 | ||||
|                 skip(parser); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 		if (isValidShare(share)) { | ||||
| 			shares.add(share); | ||||
| 		} | ||||
| 	} | ||||
|         if (isValidShare(share)) { | ||||
|             shares.add(share); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	private boolean isValidShare(OCShare share) { | ||||
| 		return (share.getRemoteId() > -1); | ||||
| 	} | ||||
|     private boolean isValidShare(OCShare share) { | ||||
|         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)) { | ||||
| 			share.setPath(share.getPath() + FileUtils.PATH_SEPARATOR); | ||||
| 		} | ||||
| 	} | ||||
|     private void fixPathForFolder(OCShare share) { | ||||
|         if (share.isFolder() && share.getPath() != null && share.getPath().length() > 0 && | ||||
|                 !share.getPath().endsWith(FileUtils.PATH_SEPARATOR)) { | ||||
|             share.setPath(share.getPath() + FileUtils.PATH_SEPARATOR); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Parse a node, to obtain its text. Needs readText method | ||||
| 	 * @param parser | ||||
| 	 * @param node | ||||
| 	 * @return Text of the node | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 * @throws IOException | ||||
| 	 */ | ||||
| 	private String readNode (XmlPullParser parser, String node) throws XmlPullParserException, | ||||
| 			IOException{ | ||||
| 		parser.require(XmlPullParser.START_TAG, ns, node); | ||||
| 		String value = readText(parser); | ||||
| 		//Log_OC.d(TAG, "node= " + node + ", value= " + value); | ||||
| 		parser.require(XmlPullParser.END_TAG, ns, node); | ||||
| 		return value; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Read the text from a node | ||||
| 	 * @param parser | ||||
| 	 * @return Text of the node | ||||
| 	 * @throws IOException | ||||
| 	 * @throws XmlPullParserException | ||||
| 	 */ | ||||
| 	private String readText(XmlPullParser parser) throws IOException, XmlPullParserException { | ||||
| 		String result = ""; | ||||
| 		if (parser.next() == XmlPullParser.TEXT) { | ||||
| 			result = parser.getText(); | ||||
| 			parser.nextTag(); | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
|     /** | ||||
|      * Parse a node, to obtain its text. Needs readText method | ||||
|      * | ||||
|      * @param parser | ||||
|      * @param node | ||||
|      * @return Text of the node | ||||
|      * @throws XmlPullParserException | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     private String readNode(XmlPullParser parser, String node) throws XmlPullParserException, | ||||
|             IOException { | ||||
|         parser.require(XmlPullParser.START_TAG, ns, node); | ||||
|         String value = readText(parser); | ||||
|         //Log_OC.d(TAG, "node= " + node + ", value= " + value); | ||||
|         parser.require(XmlPullParser.END_TAG, ns, node); | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
| 	/** | ||||
| 	 * 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; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -33,6 +33,7 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod; | ||||
| 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 okhttp3.FormBody; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| import java.text.DateFormat; | ||||
| @ -40,11 +41,9 @@ import java.text.SimpleDateFormat; | ||||
| import java.util.Calendar; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import okhttp3.FormBody; | ||||
| 
 | ||||
| /** | ||||
|  * Updates parameters of an existing Share resource, known its remote ID. | ||||
|  * | ||||
|  * <p> | ||||
|  * Allow updating several parameters, triggering a request to the server per parameter. | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
| @ -64,7 +63,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|     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 | ||||
|      */ | ||||
| @ -91,7 +89,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|     private Boolean mPublicUpload; | ||||
|     private String mName; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor. No update is initialized by default, need to be applied with setters below. | ||||
|      * | ||||
| @ -105,13 +102,12 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|         mPermissions = OCShare.DEFAULT_PERMISSION; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set name to update in Share resource. Ignored by servers previous to version 10.0.0 | ||||
|      * | ||||
|      * @param name     Name to set to the target share. | ||||
|      *                 Empty string clears the current name. | ||||
|      *                 Null results in no update applied to the name. | ||||
|      * @param name Name to set to the target share. | ||||
|      *             Empty string clears the current name. | ||||
|      *             Null results in no update applied to the name. | ||||
|      */ | ||||
|     public void setName(String name) { | ||||
|         this.mName = name; | ||||
| @ -128,7 +124,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|         mPassword = password; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set expiration date to update in Share resource. | ||||
|      * | ||||
| @ -141,7 +136,6 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|         mExpirationDateInMillis = expirationDateInMillis; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Set permissions to update in Share resource. | ||||
|      * | ||||
| @ -155,8 +149,8 @@ public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResul | ||||
|     /** | ||||
|      * Enable upload permissions to update in Share resource. | ||||
|      * | ||||
|      * @param publicUpload  Upload permission to set to the target share. | ||||
|      *                      Null results in no update applied to the upload permission. | ||||
|      * @param publicUpload Upload permission to set to the target share. | ||||
|      *                     Null results in no update applied to the upload permission. | ||||
|      */ | ||||
|     public void setPublicUpload(Boolean publicUpload) { | ||||
|         mPublicUpload = publicUpload; | ||||
|  | ||||
| @ -27,29 +27,22 @@ package com.owncloud.android.lib.resources.status; | ||||
| /** | ||||
|  * Enum for Boolean Type in OCCapability parameters, with values: | ||||
|  * -1 - Unknown | ||||
|  *  0 - False | ||||
|  *  1 - True | ||||
|  * 0 - False | ||||
|  * 1 - True | ||||
|  */ | ||||
| public enum CapabilityBooleanType { | ||||
|     UNKNOWN (-1), | ||||
|     FALSE (0), | ||||
|     TRUE (1); | ||||
|     UNKNOWN(-1), | ||||
|     FALSE(0), | ||||
|     TRUE(1); | ||||
| 
 | ||||
|     private int value; | ||||
| 
 | ||||
|     CapabilityBooleanType(int value) | ||||
|     { | ||||
|     CapabilityBooleanType(int value) { | ||||
|         this.value = value; | ||||
|     } | ||||
| 
 | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public static CapabilityBooleanType fromValue(int value) | ||||
|     { | ||||
|         switch (value) | ||||
|         { | ||||
|     public static CapabilityBooleanType fromValue(int value) { | ||||
|         switch (value) { | ||||
|             case -1: | ||||
|                 return UNKNOWN; | ||||
|             case 0: | ||||
| @ -60,23 +53,27 @@ public enum CapabilityBooleanType { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public static CapabilityBooleanType fromBooleanValue(boolean boolValue){ | ||||
|         if (boolValue){ | ||||
|     public static CapabilityBooleanType fromBooleanValue(boolean boolValue) { | ||||
|         if (boolValue) { | ||||
|             return TRUE; | ||||
|         } else { | ||||
|             return FALSE; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean isUnknown(){ | ||||
|     public int getValue() { | ||||
|         return value; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isUnknown() { | ||||
|         return getValue() == -1; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isFalse(){ | ||||
|     public boolean isFalse() { | ||||
|         return getValue() == 0; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isTrue(){ | ||||
|     public boolean isTrue() { | ||||
|         return getValue() == 1; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -24,7 +24,6 @@ | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.status; | ||||
| 
 | ||||
| import android.net.Uri; | ||||
| @ -35,7 +34,6 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| 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.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
| @ -109,10 +107,8 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|     private static final String PROPERTY_UNDELETE = "undelete"; | ||||
|     private static final String PROPERTY_VERSIONING = "versioning"; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor | ||||
|      * | ||||
|      */ | ||||
|     public GetRemoteCapabilitiesOperation() { | ||||
| 
 | ||||
| @ -135,7 +131,7 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|             int status = client.executeHttpMethod(getMethod); | ||||
| 
 | ||||
|             String response = getMethod.getResponseBodyAsString(); | ||||
|             if(isSuccess(status)) { | ||||
|             if (isSuccess(status)) { | ||||
|                 Log_OC.d(TAG, "Successful response: " + response); | ||||
| 
 | ||||
|                 // Parse the response | ||||
| @ -185,12 +181,12 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|                                 JSONObject respPublic = respFilesSharing.getJSONObject(NODE_PUBLIC); | ||||
|                                 capability.setFilesSharingPublicEnabled(CapabilityBooleanType.fromBooleanValue( | ||||
|                                         respPublic.getBoolean(PROPERTY_ENABLED))); | ||||
|                                 if(respPublic.has(NODE_PASSWORD)) { | ||||
|                                 if (respPublic.has(NODE_PASSWORD)) { | ||||
|                                     capability.setFilesSharingPublicPasswordEnforced( | ||||
|                                             CapabilityBooleanType.fromBooleanValue( | ||||
|                                             respPublic.getJSONObject(NODE_PASSWORD).getBoolean(PROPERTY_ENFORCED))); | ||||
|                                                     respPublic.getJSONObject(NODE_PASSWORD).getBoolean(PROPERTY_ENFORCED))); | ||||
|                                 } | ||||
|                                 if(respPublic.has(NODE_EXPIRE_DATE)){ | ||||
|                                 if (respPublic.has(NODE_EXPIRE_DATE)) { | ||||
|                                     JSONObject respExpireDate = respPublic.getJSONObject(NODE_EXPIRE_DATE); | ||||
|                                     capability.setFilesSharingPublicExpireDateEnabled( | ||||
|                                             CapabilityBooleanType.fromBooleanValue( | ||||
| @ -205,7 +201,7 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|                                                         respExpireDate.getBoolean(PROPERTY_ENFORCED))); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 if (respPublic.has(PROPERTY_UPLOAD)){ | ||||
|                                 if (respPublic.has(PROPERTY_UPLOAD)) { | ||||
|                                     capability.setFilesSharingPublicUpload(CapabilityBooleanType.fromBooleanValue( | ||||
|                                             respPublic.getBoolean(PROPERTY_UPLOAD))); | ||||
|                                 } | ||||
| @ -230,14 +226,13 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability | ||||
|                             if (respFilesSharing.has(NODE_FEDERATION)) { | ||||
|                                 JSONObject respFederation = respFilesSharing.getJSONObject(NODE_FEDERATION); | ||||
|                                 capability.setFilesSharingFederationOutgoing( | ||||
|                                 CapabilityBooleanType.fromBooleanValue(respFederation.getBoolean(PROPERTY_OUTGOING))); | ||||
|                                         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 | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -34,13 +34,12 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| 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.json.JSONException; | ||||
| import org.json.JSONObject; | ||||
| 
 | ||||
| import javax.net.ssl.SSLException; | ||||
| import java.net.URL; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import javax.net.ssl.SSLException; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| @ -98,11 +97,11 @@ public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> { | ||||
| 
 | ||||
|             String redirectedLocation = mLatestResult.getRedirectedLocation(); | ||||
|             while (redirectedLocation != null && redirectedLocation.length() > 0 | ||||
|                 && !mLatestResult.isSuccess()) { | ||||
|                     && !mLatestResult.isSuccess()) { | ||||
| 
 | ||||
|                 isRedirectToNonSecureConnection |= ( | ||||
|                     baseUrlSt.startsWith(HTTPS_PREFIX) && | ||||
|                         redirectedLocation.startsWith(HTTP_PREFIX) | ||||
|                         baseUrlSt.startsWith(HTTPS_PREFIX) && | ||||
|                                 redirectedLocation.startsWith(HTTP_PREFIX) | ||||
|                 ); | ||||
| 
 | ||||
|                 getMethod = new GetMethod(new URL(redirectedLocation)); | ||||
| @ -128,13 +127,13 @@ public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> { | ||||
| 
 | ||||
|                     if (isRedirectToNonSecureConnection) { | ||||
|                         mLatestResult = new RemoteOperationResult<>( | ||||
|                             RemoteOperationResult.ResultCode. | ||||
|                                 OK_REDIRECT_TO_NON_SECURE_CONNECTION); | ||||
|                                 RemoteOperationResult.ResultCode. | ||||
|                                         OK_REDIRECT_TO_NON_SECURE_CONNECTION); | ||||
|                     } else { | ||||
|                         mLatestResult = new RemoteOperationResult<>( | ||||
|                             baseUrlSt.startsWith(HTTPS_PREFIX) ? | ||||
|                                 RemoteOperationResult.ResultCode.OK_SSL : | ||||
|                                 RemoteOperationResult.ResultCode.OK_NO_SSL); | ||||
|                                 baseUrlSt.startsWith(HTTPS_PREFIX) ? | ||||
|                                         RemoteOperationResult.ResultCode.OK_SSL : | ||||
|                                         RemoteOperationResult.ResultCode.OK_NO_SSL); | ||||
|                     } | ||||
| 
 | ||||
|                     mLatestResult.setData(ocVersion); | ||||
| @ -147,7 +146,7 @@ public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> { | ||||
| 
 | ||||
|         } catch (JSONException e) { | ||||
|             mLatestResult = new RemoteOperationResult<>( | ||||
|                 RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED); | ||||
|                     RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED); | ||||
| 
 | ||||
|         } catch (Exception e) { | ||||
|             mLatestResult = new RemoteOperationResult<>(e); | ||||
| @ -158,7 +157,7 @@ public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> { | ||||
| 
 | ||||
|         } else if (mLatestResult.getException() != null) { | ||||
|             Log_OC.e(TAG, "Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage(), | ||||
|                 mLatestResult.getException()); | ||||
|                     mLatestResult.getException()); | ||||
| 
 | ||||
|         } else { | ||||
|             Log_OC.e(TAG, "Connection check at " + baseUrlSt + ": " + mLatestResult.getLogMessage()); | ||||
| @ -169,9 +168,9 @@ public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> { | ||||
| 
 | ||||
|     private boolean isOnline() { | ||||
|         ConnectivityManager cm = (ConnectivityManager) mContext | ||||
|             .getSystemService(Context.CONNECTIVITY_SERVICE); | ||||
|                 .getSystemService(Context.CONNECTIVITY_SERVICE); | ||||
|         return cm != null && cm.getActiveNetworkInfo() != null | ||||
|             && cm.getActiveNetworkInfo().isConnectedOrConnecting(); | ||||
|                 && cm.getActiveNetworkInfo().isConnectedOrConnecting(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | ||||
| @ -101,7 +101,6 @@ public class OCCapability { | ||||
|         mFilesVersioning = CapabilityBooleanType.UNKNOWN; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // Getters and Setters | ||||
|     public String getAccountName() { | ||||
|         return mAccountName; | ||||
| @ -159,7 +158,6 @@ public class OCCapability { | ||||
|         this.mVersionEdition = versionEdition; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public int getCorePollinterval() { | ||||
|         return mCorePollinterval; | ||||
|     } | ||||
| @ -216,7 +214,6 @@ public class OCCapability { | ||||
|         this.mFilesSharingPublicExpireDateEnforced = filesSharingPublicExpireDateEnforced; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public CapabilityBooleanType getFilesSharingPublicSendMail() { | ||||
|         return mFilesSharingPublicSendMail; | ||||
|     } | ||||
|  | ||||
| @ -1,23 +1,23 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *   Copyright (C) 2012  Bartek Przybylski | ||||
|  *    | ||||
|  * | ||||
|  *   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  *   of this software and associated documentation files (the "Software"), to deal | ||||
|  *   in the Software without restriction, including without limitation the rights | ||||
|  *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  *   copies of the Software, and to permit persons to whom the Software is | ||||
|  *   furnished to do so, subject to the following conditions: | ||||
|  *    | ||||
|  * | ||||
|  *   The above copyright notice and this permission notice shall be included in | ||||
|  *   all copies or substantial portions of the Software. | ||||
|  *    | ||||
|  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -106,7 +106,7 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> { | ||||
|     @Override | ||||
|     public int compareTo(OwnCloudVersion another) { | ||||
|         return another.mVersion == mVersion ? 0 | ||||
|             : another.mVersion < mVersion ? 1 : -1; | ||||
|                 : another.mVersion < mVersion ? 1 : -1; | ||||
|     } | ||||
| 
 | ||||
|     private void parseVersion(String version) { | ||||
| @ -139,7 +139,6 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> { | ||||
|         return versionValue; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public boolean isChunkedUploadSupported() { | ||||
|         return (mVersion >= MINIMUN_VERSION_FOR_CHUNKED_UPLOADS); | ||||
|     } | ||||
| @ -185,8 +184,8 @@ public class OwnCloudVersion implements Comparable<OwnCloudVersion> { | ||||
|      */ | ||||
|     public boolean isPreemptiveAuthenticationPreferred() { | ||||
|         return ( | ||||
|             (mVersion < MINIMUM_VERSION_WITH_SESSION_MONITORING) || | ||||
|                 (mVersion >= MINIMUM_VERSION_WITH_SESSION_MONITORING_WORKING_IN_PREEMPTIVE_MODE) | ||||
|                 (mVersion < MINIMUM_VERSION_WITH_SESSION_MONITORING) || | ||||
|                         (mVersion >= MINIMUM_VERSION_WITH_SESSION_MONITORING_WORKING_IN_PREEMPTIVE_MODE) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -43,6 +43,7 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
| 
 | ||||
| /** | ||||
|  * Gets avatar about the user logged in, if available | ||||
|  * | ||||
|  * @author David A. Velasco | ||||
|  * @author David González Verdugo | ||||
|  */ | ||||
| @ -52,7 +53,9 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation<GetRemoteUserA | ||||
| 
 | ||||
|     private static final String NON_OFFICIAL_AVATAR_PATH = "/index.php/avatar/"; | ||||
| 
 | ||||
|     /** Desired size in pixels of the squared image */ | ||||
|     /** | ||||
|      * Desired size in pixels of the squared image | ||||
|      */ | ||||
|     private int mDimension; | ||||
| 
 | ||||
|     /** | ||||
| @ -77,7 +80,7 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation<GetRemoteUserA | ||||
|         try { | ||||
|             final String url = | ||||
|                     client.getBaseUri() + NON_OFFICIAL_AVATAR_PATH + | ||||
|                     client.getCredentials().getUsername() + "/" + mDimension; | ||||
|                             client.getCredentials().getUsername() + "/" + mDimension; | ||||
|             Log_OC.d(TAG, "avatar URI: " + url); | ||||
| 
 | ||||
|             getMethod = new GetMethod(new URL(url)); | ||||
| @ -99,7 +102,7 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation<GetRemoteUserA | ||||
| 
 | ||||
|                 if (contentType == null || !contentType.startsWith("image")) { | ||||
|                     Log_OC.e( | ||||
|                         TAG, "Not an image, failing with no avatar" | ||||
|                             TAG, "Not an image, failing with no avatar" | ||||
|                     ); | ||||
|                     result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.FILE_NOT_FOUND); | ||||
|                     return result; | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -30,7 +30,6 @@ import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod; | ||||
| 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.json.JSONObject; | ||||
| 
 | ||||
| import java.net.URL; | ||||
|  | ||||
| @ -27,6 +27,9 @@ | ||||
| 
 | ||||
| package com.owncloud.android.lib.resources.users; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.property.QuotaAvailableBytes; | ||||
| import at.bitfire.dav4android.property.QuotaUsedBytes; | ||||
| import com.owncloud.android.lib.common.OwnCloudClient; | ||||
| import com.owncloud.android.lib.common.http.HttpConstants; | ||||
| import com.owncloud.android.lib.common.http.methods.webdav.DavUtils; | ||||
| @ -39,10 +42,6 @@ import com.owncloud.android.lib.common.utils.Log_OC; | ||||
| import java.net.URL; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import at.bitfire.dav4android.Property; | ||||
| import at.bitfire.dav4android.property.QuotaAvailableBytes; | ||||
| import at.bitfire.dav4android.property.QuotaUsedBytes; | ||||
| 
 | ||||
| import static com.owncloud.android.lib.common.http.methods.webdav.DavConstants.DEPTH_0; | ||||
| import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK; | ||||
| 
 | ||||
| @ -52,26 +51,7 @@ import static com.owncloud.android.lib.common.operations.RemoteOperationResult.R | ||||
|  */ | ||||
| public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQuotaOperation.RemoteQuota> { | ||||
| 
 | ||||
|     static public class RemoteQuota { | ||||
| 
 | ||||
|         long mFree, mUsed, mTotal; | ||||
|         double mRelative; | ||||
| 
 | ||||
|         public RemoteQuota(long free, long used, long total, double relative) { | ||||
|             mFree = free; | ||||
|             mUsed = used; | ||||
|             mTotal = total; | ||||
|             mRelative = relative; | ||||
|         } | ||||
| 
 | ||||
|         public long getFree() { return mFree; } | ||||
|         public long getUsed() { return mUsed; } | ||||
|         public long getTotal() { return mTotal; } | ||||
|         public double getRelative() { return mRelative; } | ||||
|     } | ||||
| 
 | ||||
|     private static final String TAG = GetRemoteUserQuotaOperation.class.getSimpleName(); | ||||
| 
 | ||||
|     private String mRemotePath; | ||||
| 
 | ||||
|     /** | ||||
| @ -112,7 +92,6 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|         } catch (Exception e) { | ||||
|             result = new RemoteOperationResult<>(e); | ||||
| 
 | ||||
| 
 | ||||
|         } finally { | ||||
|             if (result.isSuccess()) { | ||||
|                 Log_OC.i(TAG, "Get quota from " + mRemotePath + ": " + result.getLogMessage()); | ||||
| @ -143,11 +122,13 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|         long quotaAvailable = 0; | ||||
|         long quotaUsed = 0; | ||||
| 
 | ||||
|         for(Property property : properties) { | ||||
|             if(property instanceof QuotaAvailableBytes) | ||||
|         for (Property property : properties) { | ||||
|             if (property instanceof QuotaAvailableBytes) { | ||||
|                 quotaAvailable = ((QuotaAvailableBytes) property).getQuotaAvailableBytes(); | ||||
|             if(property instanceof QuotaUsedBytes) | ||||
|             } | ||||
|             if (property instanceof QuotaUsedBytes) { | ||||
|                 quotaUsed = ((QuotaUsedBytes) property).getQuotaUsedBytes(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // If there's a special case, quota available will contain a negative code | ||||
| @ -163,8 +144,8 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|             ); | ||||
|         } else { | ||||
|             long totalQuota = quotaAvailable + quotaUsed; | ||||
|             double relativeQuota = (double)(quotaUsed * 100)/totalQuota; | ||||
|             double roundedRelativeQuota = Math.round(relativeQuota * 100)/100.0d; | ||||
|             double relativeQuota = (double) (quotaUsed * 100) / totalQuota; | ||||
|             double roundedRelativeQuota = Math.round(relativeQuota * 100) / 100.0d; | ||||
| 
 | ||||
|             return new RemoteQuota( | ||||
|                     quotaAvailable, | ||||
| @ -174,4 +155,33 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQu | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static public class RemoteQuota { | ||||
| 
 | ||||
|         long mFree, mUsed, mTotal; | ||||
|         double mRelative; | ||||
| 
 | ||||
|         public RemoteQuota(long free, long used, long total, double relative) { | ||||
|             mFree = free; | ||||
|             mUsed = used; | ||||
|             mTotal = total; | ||||
|             mRelative = relative; | ||||
|         } | ||||
| 
 | ||||
|         public long getFree() { | ||||
|             return mFree; | ||||
|         } | ||||
| 
 | ||||
|         public long getUsed() { | ||||
|             return mUsed; | ||||
|         } | ||||
| 
 | ||||
|         public long getTotal() { | ||||
|             return mTotal; | ||||
|         } | ||||
| 
 | ||||
|         public double getRelative() { | ||||
|             return mRelative; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||||
|     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||||
| 
 | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>com.owncloud.android</groupId> | ||||
| @ -19,7 +19,7 @@ | ||||
|     </properties> | ||||
| 
 | ||||
|     <description>owncloud-android-library for Owncloud for Android</description> | ||||
|      | ||||
| 
 | ||||
|     <dependencies> | ||||
| 
 | ||||
|         <dependency> | ||||
|  | ||||
| @ -19,7 +19,7 @@ android { | ||||
|     packagingOptions { | ||||
|         exclude 'META-INF/LICENSE.txt' | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     compileOptions { | ||||
|         sourceCompatibility JavaVersion.VERSION_1_8 | ||||
|         targetCompatibility JavaVersion.VERSION_1_8 | ||||
|  | ||||
| @ -23,12 +23,12 @@ | ||||
| 
 | ||||
|  --> | ||||
| 
 | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|           package="com.owncloud.android.lib.sampleclient" | ||||
|           android:versionCode="1" | ||||
|           android:versionName="1.0"> | ||||
| <manifest package="com.owncloud.android.lib.sampleclient" | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:versionCode="1" | ||||
|     android:versionName="1.0"> | ||||
| 
 | ||||
|     <uses-permission android:name="android.permission.INTERNET"/> | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <application | ||||
|         android:icon="@drawable/ic_launcher" | ||||
|         android:label="@string/app_name"> | ||||
| @ -39,8 +39,8 @@ | ||||
|             android:screenOrientation="portrait" | ||||
|             > | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN"/> | ||||
|                 <category android:name="android.intent.category.LAUNCHER"/> | ||||
|                 <action android:name="android.intent.action.MAIN" /> | ||||
|                 <category android:name="android.intent.category.LAUNCHER" /> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|     </application> | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2016 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -32,15 +32,15 @@ import android.widget.TextView; | ||||
| import com.owncloud.android.lib.resources.files.RemoteFile; | ||||
| 
 | ||||
| public class FilesArrayAdapter extends ArrayAdapter<RemoteFile> { | ||||
| 	 | ||||
| 	public FilesArrayAdapter(Context context, int resource) { | ||||
| 		super(context, resource); | ||||
| 	} | ||||
| 	 | ||||
| 	public View getView(int position, View convertView, ViewGroup parent) { | ||||
| 		TextView textView = (TextView)super.getView(position, convertView, parent); | ||||
| 	    textView.setText(getItem(position).getRemotePath()); | ||||
| 	    return textView; | ||||
| 	}		 | ||||
| 
 | ||||
|     public FilesArrayAdapter(Context context, int resource) { | ||||
|         super(context, resource); | ||||
|     } | ||||
| 
 | ||||
|     public View getView(int position, View convertView, ViewGroup parent) { | ||||
|         TextView textView = (TextView) super.getView(position, convertView, parent); | ||||
|         textView.setText(getItem(position).getRemotePath()); | ||||
|         return textView; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| /* ownCloud Android Library is available under MIT license | ||||
|  *   Copyright (C) 2018 ownCloud GmbH. | ||||
|  *    | ||||
|  * | ||||
|  *   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,  | ||||
|  * | ||||
|  *   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  | ||||
|  *   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. | ||||
|  * | ||||
| @ -66,245 +66,245 @@ import java.util.List; | ||||
| import static android.content.ContentValues.TAG; | ||||
| 
 | ||||
| public class MainActivity extends Activity implements OnRemoteOperationListener, OnDatatransferProgressListener { | ||||
| 	 | ||||
| 	private static String LOG_TAG = MainActivity.class.getCanonicalName(); | ||||
| 	 | ||||
| 	private Handler mHandler; | ||||
| 	private OwnCloudClient mClient; | ||||
| 	private FilesArrayAdapter mFilesAdapter; | ||||
| 	private View mFrame; | ||||
| 	 | ||||
|     /** Called when the activity is first created. */ | ||||
| 
 | ||||
|     private static String LOG_TAG = MainActivity.class.getCanonicalName(); | ||||
| 
 | ||||
|     private Handler mHandler; | ||||
|     private OwnCloudClient mClient; | ||||
|     private FilesArrayAdapter mFilesAdapter; | ||||
|     private View mFrame; | ||||
| 
 | ||||
|     /** | ||||
|      * Called when the activity is first created. | ||||
|      */ | ||||
|     @Override | ||||
|     public void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
|         setContentView(R.layout.main); | ||||
|          | ||||
| 
 | ||||
|         mHandler = new Handler(); | ||||
|          | ||||
|     	final Uri serverUri = Uri.parse(getString(R.string.server_base_url)); | ||||
| 
 | ||||
| 		OwnCloudClientManagerFactory.setUserAgent(getUserAgent()); | ||||
|     	mClient = OwnCloudClientFactory.createOwnCloudClient(serverUri, this, true); | ||||
|         final Uri serverUri = Uri.parse(getString(R.string.server_base_url)); | ||||
| 
 | ||||
| 		mClient.setCredentials( | ||||
| 				OwnCloudCredentialsFactory.newBasicCredentials( | ||||
| 						getString(R.string.username), | ||||
| 						getString(R.string.password) | ||||
| 				) | ||||
| 		); | ||||
|     	 | ||||
|     	mFilesAdapter = new FilesArrayAdapter(this, R.layout.file_in_list); | ||||
|     	((ListView)findViewById(R.id.list_view)).setAdapter(mFilesAdapter); | ||||
|     	 | ||||
|     	// TODO move to background thread or task | ||||
|     	AssetManager assets = getAssets(); | ||||
| 		try { | ||||
| 			String sampleFileName = getString(R.string.sample_file_name);  | ||||
| 	    	File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
| 	    	upFolder.mkdir(); | ||||
| 	    	File upFile = new File(upFolder, sampleFileName); | ||||
| 	    	FileOutputStream fos = new FileOutputStream(upFile); | ||||
| 	    	InputStream is = assets.open(sampleFileName); | ||||
| 	    	int count = 0; | ||||
| 	    	byte[] buffer = new byte[1024]; | ||||
| 	    	while ((count = is.read(buffer, 0, buffer.length)) >= 0) { | ||||
| 	    		fos.write(buffer, 0, count); | ||||
| 	    	} | ||||
| 	    	is.close(); | ||||
| 	    	fos.close(); | ||||
| 		} catch (IOException e) { | ||||
| 			Toast.makeText(this, R.string.error_copying_sample_file, Toast.LENGTH_SHORT).show(); | ||||
| 			Log.e(LOG_TAG, getString(R.string.error_copying_sample_file), e); | ||||
| 		} | ||||
| 		 | ||||
| 		mFrame = findViewById(R.id.frame); | ||||
|         OwnCloudClientManagerFactory.setUserAgent(getUserAgent()); | ||||
|         mClient = OwnCloudClientFactory.createOwnCloudClient(serverUri, this, true); | ||||
| 
 | ||||
|         mClient.setCredentials( | ||||
|                 OwnCloudCredentialsFactory.newBasicCredentials( | ||||
|                         getString(R.string.username), | ||||
|                         getString(R.string.password) | ||||
|                 ) | ||||
|         ); | ||||
| 
 | ||||
|         mFilesAdapter = new FilesArrayAdapter(this, R.layout.file_in_list); | ||||
|         ((ListView) findViewById(R.id.list_view)).setAdapter(mFilesAdapter); | ||||
| 
 | ||||
|         // TODO move to background thread or task | ||||
|         AssetManager assets = getAssets(); | ||||
|         try { | ||||
|             String sampleFileName = getString(R.string.sample_file_name); | ||||
|             File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|             upFolder.mkdir(); | ||||
|             File upFile = new File(upFolder, sampleFileName); | ||||
|             FileOutputStream fos = new FileOutputStream(upFile); | ||||
|             InputStream is = assets.open(sampleFileName); | ||||
|             int count = 0; | ||||
|             byte[] buffer = new byte[1024]; | ||||
|             while ((count = is.read(buffer, 0, buffer.length)) >= 0) { | ||||
|                 fos.write(buffer, 0, count); | ||||
|             } | ||||
|             is.close(); | ||||
|             fos.close(); | ||||
|         } catch (IOException e) { | ||||
|             Toast.makeText(this, R.string.error_copying_sample_file, Toast.LENGTH_SHORT).show(); | ||||
|             Log.e(LOG_TAG, getString(R.string.error_copying_sample_file), e); | ||||
|         } | ||||
| 
 | ||||
|         mFrame = findViewById(R.id.frame); | ||||
|     } | ||||
|      | ||||
|      | ||||
| 
 | ||||
|     @Override | ||||
|     public void onDestroy() { | ||||
|     	File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|     	File upFile = upFolder.listFiles()[0]; | ||||
|     	upFile.delete(); | ||||
|     	upFolder.delete(); | ||||
|     	super.onDestroy(); | ||||
|         File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|         File upFile = upFolder.listFiles()[0]; | ||||
|         upFile.delete(); | ||||
|         upFolder.delete(); | ||||
|         super.onDestroy(); | ||||
|     } | ||||
|      | ||||
|      | ||||
| 
 | ||||
|     public void onClickHandler(View button) { | ||||
|     	switch (button.getId())	{ | ||||
| 	    	case R.id.button_refresh: | ||||
| 	    		startRefresh(); | ||||
| 	    		break; | ||||
| 	    	case R.id.button_upload: | ||||
| 	    		startUpload(); | ||||
| 	    		break; | ||||
| 	    	case R.id.button_delete_remote: | ||||
| 	    		startRemoteDeletion(); | ||||
| 	    		break; | ||||
| 	    	case R.id.button_download: | ||||
| 	    		startDownload(); | ||||
| 	    		break; | ||||
| 	    	case R.id.button_delete_local: | ||||
| 	    		startLocalDeletion(); | ||||
| 	    		break; | ||||
| 			default: | ||||
| 	    		Toast.makeText(this, R.string.youre_doing_it_wrong, Toast.LENGTH_SHORT).show(); | ||||
|     	} | ||||
|         switch (button.getId()) { | ||||
|             case R.id.button_refresh: | ||||
|                 startRefresh(); | ||||
|                 break; | ||||
|             case R.id.button_upload: | ||||
|                 startUpload(); | ||||
|                 break; | ||||
|             case R.id.button_delete_remote: | ||||
|                 startRemoteDeletion(); | ||||
|                 break; | ||||
|             case R.id.button_download: | ||||
|                 startDownload(); | ||||
|                 break; | ||||
|             case R.id.button_delete_local: | ||||
|                 startLocalDeletion(); | ||||
|                 break; | ||||
|             default: | ||||
|                 Toast.makeText(this, R.string.youre_doing_it_wrong, Toast.LENGTH_SHORT).show(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void startRefresh() { | ||||
| 		ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(FileUtils.PATH_SEPARATOR); | ||||
| 		refreshOperation.execute(mClient, this, mHandler); | ||||
|         ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(FileUtils.PATH_SEPARATOR); | ||||
|         refreshOperation.execute(mClient, this, mHandler); | ||||
|     } | ||||
|      | ||||
| 
 | ||||
|     private void startUpload() { | ||||
|     	File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|     	File fileToUpload = upFolder.listFiles()[0]; | ||||
|     	String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName();  | ||||
|     	String mimeType = getString(R.string.sample_file_mimetype); | ||||
|         File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|         File fileToUpload = upFolder.listFiles()[0]; | ||||
|         String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName(); | ||||
|         String mimeType = getString(R.string.sample_file_mimetype); | ||||
| 
 | ||||
| 		// Get the last modification date of the file from the file system | ||||
| 		Long timeStampLong = fileToUpload.lastModified()/1000; | ||||
| 		String timeStamp = timeStampLong.toString(); | ||||
|         // Get the last modification date of the file from the file system | ||||
|         Long timeStampLong = fileToUpload.lastModified() / 1000; | ||||
|         String timeStamp = timeStampLong.toString(); | ||||
| 
 | ||||
|     	UploadRemoteFileOperation uploadOperation = new UploadRemoteFileOperation(fileToUpload.getAbsolutePath(), | ||||
| 				remotePath, mimeType, timeStamp); | ||||
|     	uploadOperation.addDatatransferProgressListener(this); | ||||
|     	uploadOperation.execute(mClient, this, mHandler); | ||||
|         UploadRemoteFileOperation uploadOperation = new UploadRemoteFileOperation(fileToUpload.getAbsolutePath(), | ||||
|                 remotePath, mimeType, timeStamp); | ||||
|         uploadOperation.addDatatransferProgressListener(this); | ||||
|         uploadOperation.execute(mClient, this, mHandler); | ||||
|     } | ||||
| 
 | ||||
|     private void startRemoteDeletion() { | ||||
| 		File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
| 		File fileToUpload = upFolder.listFiles()[0]; | ||||
| 		String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName(); | ||||
|         File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|         File fileToUpload = upFolder.listFiles()[0]; | ||||
|         String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName(); | ||||
| 
 | ||||
|     	RemoveRemoteFileOperation removeOperation = new RemoveRemoteFileOperation(remotePath); | ||||
|     	removeOperation.execute(mClient, this, mHandler); | ||||
|         RemoveRemoteFileOperation removeOperation = new RemoveRemoteFileOperation(remotePath); | ||||
|         removeOperation.execute(mClient, this, mHandler); | ||||
|     } | ||||
| 
 | ||||
|     private void startDownload() { | ||||
|     	File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path)); | ||||
|     	downFolder.mkdir(); | ||||
|     	File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|     	File fileToUpload = upFolder.listFiles()[0]; | ||||
|     	String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName(); | ||||
|         File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path)); | ||||
|         downFolder.mkdir(); | ||||
|         File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path)); | ||||
|         File fileToUpload = upFolder.listFiles()[0]; | ||||
|         String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName(); | ||||
| 
 | ||||
|     	DownloadRemoteFileOperation downloadOperation = new DownloadRemoteFileOperation(remotePath, | ||||
| 				downFolder.getAbsolutePath()); | ||||
|     	downloadOperation.addDatatransferProgressListener(this); | ||||
|     	downloadOperation.execute(mClient, this, mHandler); | ||||
|         DownloadRemoteFileOperation downloadOperation = new DownloadRemoteFileOperation(remotePath, | ||||
|                 downFolder.getAbsolutePath()); | ||||
|         downloadOperation.addDatatransferProgressListener(this); | ||||
|         downloadOperation.execute(mClient, this, mHandler); | ||||
|     } | ||||
| 
 | ||||
| 	private void startLocalDeletion() { | ||||
|     	File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path)); | ||||
|     	File downloadedFile = downFolder.listFiles()[0]; | ||||
|     	if (!downloadedFile.delete() && downloadedFile.exists()) { | ||||
|     		Toast.makeText(this, R.string.error_deleting_local_file, Toast.LENGTH_SHORT).show(); | ||||
|     	} else { | ||||
|     		((TextView) findViewById(R.id.download_progress)).setText("0%"); | ||||
|     		findViewById(R.id.frame).setBackgroundDrawable(null); | ||||
|     	} | ||||
|     private void startLocalDeletion() { | ||||
|         File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path)); | ||||
|         File downloadedFile = downFolder.listFiles()[0]; | ||||
|         if (!downloadedFile.delete() && downloadedFile.exists()) { | ||||
|             Toast.makeText(this, R.string.error_deleting_local_file, Toast.LENGTH_SHORT).show(); | ||||
|         } else { | ||||
|             ((TextView) findViewById(R.id.download_progress)).setText("0%"); | ||||
|             findViewById(R.id.frame).setBackgroundDrawable(null); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { | ||||
| 		if (!result.isSuccess()) { | ||||
| 			Toast.makeText(this, R.string.todo_operation_finished_in_fail, Toast.LENGTH_SHORT).show(); | ||||
| 			Log.e(LOG_TAG, result.getLogMessage(), result.getException()); | ||||
| 			 | ||||
| 		} else if (operation instanceof ReadRemoteFolderOperation) { | ||||
| 			onSuccessfulRefresh((ReadRemoteFolderOperation)operation, result); | ||||
| 			 | ||||
| 		} else if (operation instanceof com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) { | ||||
| 			onSuccessfulUpload((com.owncloud.android.lib.resources.files.UploadRemoteFileOperation)operation, result); | ||||
| 			 | ||||
| 		} else if (operation instanceof RemoveRemoteFileOperation ) { | ||||
| 			onSuccessfulRemoteDeletion((RemoveRemoteFileOperation)operation, result); | ||||
|     @Override | ||||
|     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { | ||||
|         if (!result.isSuccess()) { | ||||
|             Toast.makeText(this, R.string.todo_operation_finished_in_fail, Toast.LENGTH_SHORT).show(); | ||||
|             Log.e(LOG_TAG, result.getLogMessage(), result.getException()); | ||||
| 
 | ||||
| 		} else if (operation instanceof DownloadRemoteFileOperation ) { | ||||
| 			onSuccessfulDownload(); | ||||
| 			 | ||||
| 		} else { | ||||
| 			Toast.makeText(this, R.string.todo_operation_finished_in_success, Toast.LENGTH_SHORT).show(); | ||||
| 		} | ||||
| 	} | ||||
|         } else if (operation instanceof ReadRemoteFolderOperation) { | ||||
|             onSuccessfulRefresh((ReadRemoteFolderOperation) operation, result); | ||||
| 
 | ||||
| 	private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) { | ||||
| 		mFilesAdapter.clear(); | ||||
| 		List<RemoteFile> files = new ArrayList<>(); | ||||
|         for(RemoteFile remoteFile: (List<RemoteFile>) result.getData()) { | ||||
|         } else if (operation instanceof com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) { | ||||
|             onSuccessfulUpload((com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) operation, result); | ||||
| 
 | ||||
|         } else if (operation instanceof RemoveRemoteFileOperation) { | ||||
|             onSuccessfulRemoteDeletion((RemoveRemoteFileOperation) operation, result); | ||||
| 
 | ||||
|         } else if (operation instanceof DownloadRemoteFileOperation) { | ||||
|             onSuccessfulDownload(); | ||||
| 
 | ||||
|         } else { | ||||
|             Toast.makeText(this, R.string.todo_operation_finished_in_success, Toast.LENGTH_SHORT).show(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) { | ||||
|         mFilesAdapter.clear(); | ||||
|         List<RemoteFile> files = new ArrayList<>(); | ||||
|         for (RemoteFile remoteFile : (List<RemoteFile>) result.getData()) { | ||||
|             files.add(remoteFile); | ||||
|         } | ||||
| 		if (files != null) { | ||||
| 			Iterator<RemoteFile> it = files.iterator(); | ||||
| 			while (it.hasNext()) { | ||||
| 				mFilesAdapter.add(it.next()); | ||||
| 			} | ||||
| 			mFilesAdapter.remove(mFilesAdapter.getItem(0)); | ||||
| 		} | ||||
| 		mFilesAdapter.notifyDataSetChanged(); | ||||
| 	} | ||||
|         if (files != null) { | ||||
|             Iterator<RemoteFile> it = files.iterator(); | ||||
|             while (it.hasNext()) { | ||||
|                 mFilesAdapter.add(it.next()); | ||||
|             } | ||||
|             mFilesAdapter.remove(mFilesAdapter.getItem(0)); | ||||
|         } | ||||
|         mFilesAdapter.notifyDataSetChanged(); | ||||
|     } | ||||
| 
 | ||||
| 	private void onSuccessfulUpload(com.owncloud.android.lib.resources.files.UploadRemoteFileOperation operation, RemoteOperationResult result) { | ||||
| 		startRefresh(); | ||||
| 	} | ||||
|     private void onSuccessfulUpload(com.owncloud.android.lib.resources.files.UploadRemoteFileOperation operation, RemoteOperationResult result) { | ||||
|         startRefresh(); | ||||
|     } | ||||
| 
 | ||||
| 	private void onSuccessfulRemoteDeletion(RemoveRemoteFileOperation operation, RemoteOperationResult result) { | ||||
| 		startRefresh(); | ||||
| 		TextView progressView = (TextView) findViewById(R.id.upload_progress); | ||||
| 		if (progressView != null) { | ||||
| 			progressView.setText("0%"); | ||||
| 		} | ||||
| 	} | ||||
|     private void onSuccessfulRemoteDeletion(RemoveRemoteFileOperation operation, RemoteOperationResult result) { | ||||
|         startRefresh(); | ||||
|         TextView progressView = (TextView) findViewById(R.id.upload_progress); | ||||
|         if (progressView != null) { | ||||
|             progressView.setText("0%"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 	private void onSuccessfulDownload() { | ||||
|     	File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path)); | ||||
|     	File downloadedFile = downFolder.listFiles()[0]; | ||||
|     	BitmapDrawable bDraw = new BitmapDrawable(getResources(), downloadedFile.getAbsolutePath()); | ||||
|     	mFrame.setBackgroundDrawable(bDraw); | ||||
| 	} | ||||
|     private void onSuccessfulDownload() { | ||||
|         File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path)); | ||||
|         File downloadedFile = downFolder.listFiles()[0]; | ||||
|         BitmapDrawable bDraw = new BitmapDrawable(getResources(), downloadedFile.getAbsolutePath()); | ||||
|         mFrame.setBackgroundDrawable(bDraw); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileName) { | ||||
| 		final long percentage = (totalToTransfer > 0 ? totalTransferredSoFar * 100 / totalToTransfer : 0); | ||||
| 		final boolean upload = fileName.contains(getString(R.string.upload_folder_path)); | ||||
| 		Log.d(LOG_TAG, "progressRate " + percentage); | ||||
|     	mHandler.post(new Runnable() { | ||||
|     @Override | ||||
|     public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileName) { | ||||
|         final long percentage = (totalToTransfer > 0 ? totalTransferredSoFar * 100 / totalToTransfer : 0); | ||||
|         final boolean upload = fileName.contains(getString(R.string.upload_folder_path)); | ||||
|         Log.d(LOG_TAG, "progressRate " + percentage); | ||||
|         mHandler.post(new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
| 				TextView progressView = null; | ||||
| 				if (upload) { | ||||
| 					progressView = findViewById(R.id.upload_progress); | ||||
| 				} else { | ||||
| 					progressView = findViewById(R.id.download_progress); | ||||
| 				} | ||||
| 				if (progressView != null) { | ||||
| 	    			progressView.setText(Long.toString(percentage) + "%"); | ||||
| 				} | ||||
|                 TextView progressView = null; | ||||
|                 if (upload) { | ||||
|                     progressView = findViewById(R.id.upload_progress); | ||||
|                 } else { | ||||
|                     progressView = findViewById(R.id.download_progress); | ||||
|                 } | ||||
|                 if (progressView != null) { | ||||
|                     progressView.setText(Long.toString(percentage) + "%"); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
| 	// user agent | ||||
| 	@SuppressLint("StringFormatInvalid") | ||||
| 	private String getUserAgent() { | ||||
| 		String appString = getResources().getString(R.string.user_agent); | ||||
| 		String packageName = getPackageName(); | ||||
| 		String version = ""; | ||||
|     // user agent | ||||
|     @SuppressLint("StringFormatInvalid") | ||||
|     private String getUserAgent() { | ||||
|         String appString = getResources().getString(R.string.user_agent); | ||||
|         String packageName = getPackageName(); | ||||
|         String version = ""; | ||||
| 
 | ||||
| 		PackageInfo pInfo; | ||||
| 		try { | ||||
| 			pInfo = getPackageManager().getPackageInfo(packageName, 0); | ||||
| 			if (pInfo != null) { | ||||
| 				version = pInfo.versionName; | ||||
| 			} | ||||
| 		} catch (PackageManager.NameNotFoundException e) { | ||||
| 			Log_OC.e(TAG, "Trying to get packageName", e.getCause()); | ||||
| 		} | ||||
|         PackageInfo pInfo; | ||||
|         try { | ||||
|             pInfo = getPackageManager().getPackageInfo(packageName, 0); | ||||
|             if (pInfo != null) { | ||||
|                 version = pInfo.versionName; | ||||
|             } | ||||
|         } catch (PackageManager.NameNotFoundException e) { | ||||
|             Log_OC.e(TAG, "Trying to get packageName", e.getCause()); | ||||
|         } | ||||
| 
 | ||||
| 		// Mozilla/5.0 (Android) ownCloud-android/1.7.0 | ||||
| 		return String.format(appString, version); | ||||
| 	} | ||||
|         // Mozilla/5.0 (Android) ownCloud-android/1.7.0 | ||||
|         return String.format(appString, version); | ||||
|     } | ||||
| } | ||||
| @ -22,8 +22,8 @@ | ||||
|    THE SOFTWARE. | ||||
| 
 | ||||
|  --> | ||||
|   | ||||
| 
 | ||||
| <TextView xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content"	 | ||||
| /> | ||||
|     android:layout_height="wrap_content" | ||||
|     /> | ||||
|  | ||||
| @ -33,58 +33,58 @@ | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_alignParentTop="true" | ||||
|         android:text="@string/refresh" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/refresh" | ||||
|         /> | ||||
| 
 | ||||
|     <ListView | ||||
|         android:id="@+id/list_view" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" | ||||
| 		android:layout_below="@+id/button_refresh" | ||||
|         android:layout_above="@+id/button_upload" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:layout_below="@+id/button_refresh" | ||||
|         > | ||||
|     </ListView> | ||||
| 
 | ||||
|     <Button | ||||
|         android:id="@+id/button_upload" | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_above="@+id/frame" | ||||
|         android:text="@string/upload" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/upload" | ||||
|         /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/upload_progress" | ||||
|         style="@style/ProgressStyle" | ||||
|         android:layout_below="@id/list_view" | ||||
|         android:layout_above="@id/frame" | ||||
|         android:layout_toRightOf="@id/button_upload" | ||||
|         android:layout_below="@id/list_view" | ||||
|         android:layout_toLeftOf="@+id/button_delete_remote" | ||||
|         android:layout_toRightOf="@id/button_upload" | ||||
|         android:gravity="center" | ||||
|         android:textSize="14sp" | ||||
|         android:text="0%" | ||||
|         android:textSize="14sp" | ||||
|         /> | ||||
| 
 | ||||
|     <Button | ||||
|         android:id="@id/button_delete_remote" | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:layout_above="@id/frame" | ||||
|         android:text="@string/delete_remote_file" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/delete_remote_file" | ||||
|         /> | ||||
| 
 | ||||
|     <FrameLayout | ||||
|         android:id="@id/frame" | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="@dimen/frame_height" | ||||
|         android:layout_above="@+id/button_download" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:layout_above="@+id/button_download" | ||||
|         > | ||||
|     </FrameLayout> | ||||
| 
 | ||||
| @ -93,20 +93,20 @@ | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_alignParentLeft="true" | ||||
|         android:text="@string/download" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/download" | ||||
|         /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/download_progress" | ||||
|         style="@style/ProgressStyle" | ||||
|         android:layout_below="@id/frame" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_toRightOf="@id/button_download" | ||||
|         android:layout_below="@id/frame" | ||||
|         android:layout_toLeftOf="@+id/button_delete_local" | ||||
|         android:layout_toRightOf="@id/button_download" | ||||
|         android:gravity="center" | ||||
|         android:textSize="14sp" | ||||
|         android:text="0%" | ||||
|         android:textSize="14sp" | ||||
|         /> | ||||
| 
 | ||||
|     <Button | ||||
| @ -114,8 +114,8 @@ | ||||
|         style="@style/ButtonStyle" | ||||
|         android:layout_alignParentBottom="true" | ||||
|         android:layout_alignParentRight="true" | ||||
|         android:text="@string/delete_local_file" | ||||
|         android:onClick="onClickHandler" | ||||
|         android:text="@string/delete_local_file" | ||||
|         /> | ||||
| 
 | ||||
| </RelativeLayout> | ||||
|  | ||||
| @ -22,13 +22,15 @@ | ||||
|    THE SOFTWARE. | ||||
| 
 | ||||
|  --> | ||||
|   | ||||
| 
 | ||||
| <resources xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
| 
 | ||||
|     <style name="ButtonStyle" parent="@android:style/Widget.Holo.Button"> | ||||
|         <item name="android:layout_width">120dp</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
|         <item name="android:textSize">12sp</item> | ||||
|     </style> | ||||
| 
 | ||||
|     <style name="ProgressStyle" parent="@android:style/Widget.Holo.TextView"> | ||||
|         <item name="android:layout_width">wrap_content</item> | ||||
|         <item name="android:layout_height">wrap_content</item> | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|    THE SOFTWARE. | ||||
| 
 | ||||
|  --> | ||||
|   | ||||
| 
 | ||||
| <resources> | ||||
|     <dimen name="frame_height">120dp</dimen> | ||||
| </resources> | ||||
| @ -26,5 +26,5 @@ | ||||
|     <string name="server_base_url"></string> | ||||
|     <string name="username"></string> | ||||
|     <string name="password"></string> | ||||
|     <string name ="user_agent">Mozilla/5.0 (Android) ownCloud sample </string> | ||||
|     <string name="user_agent">Mozilla/5.0 (Android) ownCloud sample </string> | ||||
| </resources> | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user