2  *   ownCloud Android client application 
   4  *   @author David A. Velasco 
   5  *   Copyright (C) 2015 ownCloud Inc. 
   7  *   This program is free software: you can redistribute it and/or modify 
   8  *   it under the terms of the GNU General Public License version 2, 
   9  *   as published by the Free Software Foundation. 
  11  *   This program is distributed in the hope that it will be useful, 
  12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  14  *   GNU General Public License for more details. 
  16  *   You should have received a copy of the GNU General Public License 
  17  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  22 package com
.owncloud
.android
.providers
; 
  24 import android
.accounts
.Account
; 
  25 import android
.app
.SearchManager
; 
  26 import android
.content
.ContentProvider
; 
  27 import android
.content
.ContentValues
; 
  28 import android
.content
.UriMatcher
; 
  29 import android
.database
.Cursor
; 
  30 import android
.database
.MatrixCursor
; 
  31 import android
.net
.Uri
; 
  32 import android
.provider
.BaseColumns
; 
  33 import android
.support
.annotation
.Nullable
; 
  35 import com
.owncloud
.android
.R
; 
  36 import com
.owncloud
.android
.authentication
.AccountUtils
; 
  37 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
; 
  38 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
; 
  39 import com
.owncloud
.android
.lib
.resources
.shares
.GetRemoteShareesOperation
; 
  41 import org
.json
.JSONException
; 
  42 import org
.json
.JSONObject
; 
  44 import java
.util
.ArrayList
; 
  45 import java
.util
.Iterator
; 
  46 import java
.util
.List
; 
  50  * Content provider for search suggestions, to search for users and groups existing in an ownCloud server. 
  52 public class UsersAndGroupsSearchProvider 
extends ContentProvider 
{ 
  54     private static final String TAG 
= UsersAndGroupsSearchProvider
.class.getSimpleName(); 
  56     private static final String
[] COLUMNS 
= { 
  58         SearchManager
.SUGGEST_COLUMN_TEXT_1
, 
  59         SearchManager
.SUGGEST_COLUMN_INTENT_DATA
 
  62     private static final int SEARCH 
= 1; 
  64     private static final int RESULTS_PER_PAGE 
= 50; 
  65     private static final int REQUESTED_PAGE 
= 1; 
  67     public static final String AUTHORITY 
= UsersAndGroupsSearchProvider
.class.getCanonicalName(); 
  68     public static final String ACTION_SHARE_WITH 
= AUTHORITY 
+ ".action.SHARE_WITH"; 
  69     public static final String DATA_USER 
= AUTHORITY 
+ ".data.user"; 
  70     public static final String DATA_GROUP 
= AUTHORITY 
+ ".data.group"; 
  72     private UriMatcher mUriMatcher
; 
  76     public String 
getType(Uri uri
) { 
  82     public boolean onCreate() { 
  83         mUriMatcher 
= new UriMatcher(UriMatcher
.NO_MATCH
); 
  84         mUriMatcher
.addURI(AUTHORITY
, SearchManager
.SUGGEST_URI_PATH_QUERY 
+ "/*", SEARCH
); 
  91      * Reference: http://developer.android.com/guide/topics/search/adding-custom-suggestions.html#CustomContentProvider 
  93      * @param uri           Content {@link Uri}, formattted as 
  94      *                      "content://com.owncloud.android.providers.UsersAndGroupsSearchProvider/" + 
  95      *                      {@link android.app.SearchManager#SUGGEST_URI_PATH_QUERY} + "/" + 'userQuery' 
  96      * @param projection    Expected to be NULL. 
  97      * @param selection     Expected to be NULL. 
  98      * @param selectionArgs Expected to be NULL. 
  99      * @param sortOrder     Expected to be NULL. 
 100      * @return              Cursor with users and groups in the ownCloud server that match 'userQuery'. 
 104     public Cursor 
query(Uri uri
, String
[] projection
, String selection
, String
[] selectionArgs
, String sortOrder
) { 
 105         Log_OC
.d(TAG
, "query received in thread " + Thread
.currentThread().getName()); 
 107         int match 
= mUriMatcher
.match(uri
); 
 110                 return searchForUsersOrGroups(uri
); 
 117     private Cursor 
searchForUsersOrGroups(Uri uri
) { 
 118         MatrixCursor response 
= null
; 
 121         String userQuery 
= uri
.getLastPathSegment().toLowerCase(); 
 124         /// need to trust on the AccountUtils to get the current account since the query in the client side is not 
 125         /// directly started by our code, but from SearchView implementation 
 126         Account account 
= AccountUtils
.getCurrentOwnCloudAccount(getContext()); 
 128         /// request to the OC server about users and groups matching userQuery 
 129         GetRemoteShareesOperation searchRequest 
= new GetRemoteShareesOperation( 
 130                 userQuery
, REQUESTED_PAGE
, RESULTS_PER_PAGE
 
 132         RemoteOperationResult result 
= searchRequest
.execute(account
, getContext()); 
 133         List
<JSONObject
> names 
= new ArrayList
<JSONObject
>(); 
 134         if (result
.isSuccess()) { 
 135             for (Object o 
: result
.getData()) { 
 136                 // Get JSonObjects from response 
 137                 names
.add((JSONObject
) o
); 
 141         /// convert the responses from the OC server to the expected format 
 142         if (names
.size() > 0) { 
 143             response 
= new MatrixCursor(COLUMNS
); 
 144             Iterator
<JSONObject
> namesIt 
= names
.iterator(); 
 149             Uri userBaseUri 
= new Uri
.Builder().scheme("content").authority(DATA_USER
).build(); 
 150             Uri groupBaseUri 
= new Uri
.Builder().scheme("content").authority(DATA_GROUP
).build(); 
 152                 while (namesIt
.hasNext()) { 
 153                     item 
= namesIt
.next(); 
 154                     String userName 
= item
.getString(GetRemoteShareesOperation
.PROPERTY_LABEL
); 
 155                     JSONObject value 
= item
.getJSONObject(GetRemoteShareesOperation
.NODE_VALUE
); 
 156                     byte type 
= (byte) value
.getInt(GetRemoteShareesOperation
.PROPERTY_SHARE_TYPE
); 
 157                     String shareWith 
= value
.getString(GetRemoteShareesOperation
.PROPERTY_SHARE_WITH
); 
 158                     if (GetRemoteShareesOperation
.GROUP_TYPE
.equals(type
)) { 
 159                         displayName 
= getContext().getString(R
.string
.share_group_clarification
, userName
); 
 160                         dataUri 
= Uri
.withAppendedPath(groupBaseUri
, shareWith
); 
 162                         displayName 
= userName
; 
 163                         dataUri 
= Uri
.withAppendedPath(userBaseUri
, shareWith
); 
 166                             .add(count
++)             // BaseColumns._ID 
 167                             .add(displayName
)         // SearchManager.SUGGEST_COLUMN_TEXT_1 
 170             } catch (JSONException e
) { 
 171                 Log_OC
.e(TAG
, "Exception while parsing data of users/groups", e
); 
 180     public Uri 
insert(Uri uri
, ContentValues values
) { 
 181         // TODO implementation 
 186     public int delete(Uri uri
, String selection
, String
[] selectionArgs
) { 
 187         // TODO implementation 
 192     public int update(Uri uri
, ContentValues values
, String selection
, String
[] selectionArgs
) { 
 193         // TODO implementation