Merge branch 'material_buttons' of https://github.com/owncloud/android into material_fab
[pub/Android/ownCloud.git] / src / com / owncloud / android / providers / UsersAndGroupsSearchProvider.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author David A. Velasco
5 * Copyright (C) 2015 ownCloud Inc.
6 *
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.
10 *
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.
15 *
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/>.
18 *
19 */
20
21
22 package com.owncloud.android.providers;
23
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;
34
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;
40
41 import org.json.JSONException;
42 import org.json.JSONObject;
43
44 import java.util.ArrayList;
45 import java.util.Iterator;
46 import java.util.List;
47
48
49 /**
50 * Content provider for search suggestions, to search for users and groups existing in an ownCloud server.
51 */
52 public class UsersAndGroupsSearchProvider extends ContentProvider {
53
54 private static final String TAG = UsersAndGroupsSearchProvider.class.getSimpleName();
55
56 private static final String[] COLUMNS = {
57 BaseColumns._ID,
58 SearchManager.SUGGEST_COLUMN_TEXT_1,
59 SearchManager.SUGGEST_COLUMN_INTENT_DATA
60 };
61
62 private static final int SEARCH = 1;
63
64 private static final int RESULTS_PER_PAGE = 50;
65 private static final int REQUESTED_PAGE = 1;
66
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";
71
72 private UriMatcher mUriMatcher;
73
74 @Nullable
75 @Override
76 public String getType(Uri uri) {
77 // TODO implement
78 return null;
79 }
80
81 @Override
82 public boolean onCreate() {
83 mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
84 mUriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH);
85 return true;
86 }
87
88 /**
89 * TODO description
90 *
91 * Reference: http://developer.android.com/guide/topics/search/adding-custom-suggestions.html#CustomContentProvider
92 *
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'.
101 */
102 @Nullable
103 @Override
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());
106
107 int match = mUriMatcher.match(uri);
108 switch (match) {
109 case SEARCH:
110 return searchForUsersOrGroups(uri);
111
112 default:
113 return null;
114 }
115 }
116
117 private Cursor searchForUsersOrGroups(Uri uri) {
118 MatrixCursor response = null;
119
120
121 String userQuery = uri.getLastPathSegment().toLowerCase();
122
123
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());
127
128 /// request to the OC server about users and groups matching userQuery
129 GetRemoteShareesOperation searchRequest = new GetRemoteShareesOperation(
130 userQuery, REQUESTED_PAGE, RESULTS_PER_PAGE
131 );
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);
138 }
139 }
140
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();
145 int count = 0;
146 JSONObject item;
147 String displayName;
148 Uri dataUri;
149 Uri userBaseUri = new Uri.Builder().scheme("content").authority(DATA_USER).build();
150 Uri groupBaseUri = new Uri.Builder().scheme("content").authority(DATA_GROUP).build();
151 try {
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);
161 } else {
162 displayName = userName;
163 dataUri = Uri.withAppendedPath(userBaseUri, shareWith);
164 }
165 response.newRow()
166 .add(count++) // BaseColumns._ID
167 .add(displayName) // SearchManager.SUGGEST_COLUMN_TEXT_1
168 .add(dataUri);
169 }
170 } catch (JSONException e) {
171 Log_OC.e(TAG, "Exception while parsing data of users/groups", e);
172 }
173 }
174
175 return response;
176 }
177
178 @Nullable
179 @Override
180 public Uri insert(Uri uri, ContentValues values) {
181 // TODO implementation
182 return null;
183 }
184
185 @Override
186 public int delete(Uri uri, String selection, String[] selectionArgs) {
187 // TODO implementation
188 return 0;
189 }
190
191 @Override
192 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
193 // TODO implementation
194 return 0;
195 }
196
197 }