afcc6aa420306ccba2bbb2ac2d9e593195b967b2
[platform/upstream/iotivity.git] /
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.accountserver.resources.acl.invite;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27
28 import org.iotivity.cloud.accountserver.Constants;
29 import org.iotivity.cloud.accountserver.db.AccountDBManager;
30 import org.iotivity.cloud.accountserver.db.InviteTable;
31 import org.iotivity.cloud.accountserver.resources.acl.group.GroupBrokerManager;
32 import org.iotivity.cloud.accountserver.resources.acl.group.GroupManager;
33 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
34 import org.iotivity.cloud.base.device.Device;
35 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
36 import org.iotivity.cloud.base.protocols.IRequest;
37 import org.iotivity.cloud.base.protocols.MessageBuilder;
38 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
39 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
40 import org.iotivity.cloud.util.Cbor;
41
42 /**
43  *
44  * This class provides a set of APIs to invite a user to a group
45  *
46  */
47 public class InviteManager {
48
49     private TypeCastingManager<InviteTable> mTypeInvite = new TypeCastingManager<>();
50
51     private class InviteSubscriber {
52         InviteSubscriber(Device subscriber, IRequest request) {
53             mSubscriber = subscriber;
54             mRequest = request;
55         }
56
57         public Device   mSubscriber;
58         public IRequest mRequest;
59     }
60
61     // <uid, subscriber list>
62     private HashMap<String, ArrayList<InviteSubscriber>> mSubscribers = new HashMap<>();
63
64     /**
65      * API to add invitation
66      * 
67      * @param uid
68      *            id of user who sent invitation
69      * @param gid
70      *            id of group to invite member to
71      * @param mid
72      *            id of invited user
73      */
74     public void addInvitation(String uid, String gid, String mid) {
75
76         // create invitation table
77         InviteTable newInviteTable = new InviteTable(uid, gid, mid);
78
79         HashMap<String, Object> condition = new HashMap<>();
80         condition.put(Constants.KEYFIELD_INVITE_USER, uid);
81         condition.put(Constants.KEYFIELD_GID, gid);
82         condition.put(Constants.KEYFIELD_INVITED_USER, mid);
83
84         if (AccountDBManager.getInstance()
85                 .selectRecord(Constants.INVITE_TABLE, condition).isEmpty()) {
86             AccountDBManager.getInstance().insertRecord(Constants.INVITE_TABLE,
87                     mTypeInvite.convertObjectToMap(newInviteTable));
88             notifyToSubscriber(uid);
89             notifyToSubscriber(mid);
90         }
91     }
92
93     /**
94      * API to delete invitation by invited user
95      * 
96      * @param mid
97      *            id of invited user
98      * @param gid
99      *            id of group which the user was invited to
100      * @param accepted
101      *            value of invitation accept or deny
102      */
103     public void deleteInvitation(String mid, String gid, boolean accepted) {
104         HashMap<String, Object> condition = new HashMap<>();
105         condition.put(Constants.REQ_GROUP_ID, gid);
106         condition.put(Constants.KEYFIELD_INVITED_USER, mid);
107
108         InviteTable getInviteTable = new InviteTable();
109
110         List<HashMap<String, Object>> getInviteList = AccountDBManager
111                 .getInstance().selectRecord(Constants.INVITE_TABLE, condition);
112
113         ArrayList<String> uidList = new ArrayList<>();
114         for (HashMap<String, Object> getInvite : getInviteList) {
115             getInviteTable = mTypeInvite.convertMaptoObject(getInvite,
116                     getInviteTable);
117             uidList.add(getInviteTable.getInviteUser());
118         }
119
120         if (getInviteList == null || getInviteList.isEmpty()) {
121             throw new BadRequestException("mid or gid is not valid");
122         }
123
124         AccountDBManager.getInstance().deleteRecord(Constants.INVITE_TABLE,
125                 condition);
126
127         /* add user into group */
128         if (accepted) {
129
130             ArrayList<String> midlist = new ArrayList<>();
131             midlist.add(mid);
132
133             GroupManager.getInstance().addMembersToGroup(gid, midlist);
134             GroupBrokerManager.getInstance().notifyToObservers(
135                     GroupManager.getInstance().getGroupTable(gid).getMembers());
136         }
137
138         notifyToSubscriber(mid);
139         for (String uid : uidList) {
140             notifyToSubscriber(uid);
141         }
142     }
143
144     /**
145      * API to cancel invitation by user who invited member
146      * 
147      * @param uid
148      *            id of user who sent invitation
149      * @param gid
150      *            id of group to invite member to
151      * @param mid
152      *            id of invited user
153      */
154     public void cancelInvitation(String uid, String gid, String mid) {
155
156         HashMap<String, Object> condition = new HashMap<>();
157
158         condition.put(Constants.REQ_GROUP_ID, gid);
159         condition.put(Constants.KEYFIELD_INVITED_USER, mid);
160         condition.put(Constants.KEYFIELD_INVITE_USER, uid);
161
162         AccountDBManager.getInstance().deleteRecord(Constants.INVITE_TABLE,
163                 condition);
164
165         notifyToSubscriber(uid);
166         notifyToSubscriber(mid);
167     }
168
169     /**
170      * API to get invitation information
171      * 
172      * @param uid
173      *            user id
174      * 
175      * @return returns invite and invited information of the user
176      */
177     public HashMap<String, Object> getInvitationInfo(String uid) {
178         HashMap<String, Object> responsePayload = new HashMap<>();
179
180         ArrayList<Object> invitePayloadData = null;
181         ArrayList<Object> invitedPayloadData = null;
182
183         List<InviteTable> inviteList = getInviteTableList(
184                 Constants.KEYFIELD_INVITE_USER, uid);
185         if (!inviteList.isEmpty()) {
186             invitePayloadData = new ArrayList<>();
187             for (InviteTable invite : inviteList) {
188                 HashMap<String, String> inviteElement = new HashMap<>();
189                 inviteElement.put(Constants.REQ_GROUP_ID, invite.getGid());
190                 inviteElement.put(Constants.REQ_MEMBER,
191                         invite.getInvitedUser());
192                 invitePayloadData.add(inviteElement);
193             }
194         }
195
196         List<InviteTable> invitedList = getInviteTableList(
197                 Constants.KEYFIELD_INVITED_USER, uid);
198         if (!invitedList.isEmpty()) {
199             invitedPayloadData = new ArrayList<>();
200             for (InviteTable invited : invitedList) {
201                 HashMap<String, String> invitedElement = new HashMap<>();
202                 invitedElement.put(Constants.REQ_GROUP_ID, invited.getGid());
203                 invitedElement.put(Constants.REQ_MEMBER,
204                         invited.getInviteUser());
205                 invitedPayloadData.add(invitedElement);
206             }
207         }
208
209         responsePayload.put(Constants.RESP_INVITE, invitePayloadData);
210         responsePayload.put(Constants.RESP_INVITED, invitedPayloadData);
211
212         return responsePayload;
213     }
214
215     /**
216      * API to add subscriber of invite resource
217      * 
218      * @param uid
219      *            user id
220      * @param subscriber
221      *            device that sent request for subscription
222      * @param request
223      *            received request for subscription
224      * 
225      * @return returns invite and invited information of the user
226      */
227     public HashMap<String, Object> addSubscriber(String uid, Device subscriber,
228             IRequest request) {
229
230         InviteSubscriber newSubscriber = new InviteSubscriber(subscriber,
231                 request);
232
233         synchronized (mSubscribers) {
234             ArrayList<InviteSubscriber> subscriberList = mSubscribers.get(uid);
235
236             if (subscriberList == null) {
237                 subscriberList = new ArrayList<>();
238             }
239
240             subscriberList.add(newSubscriber);
241             mSubscribers.put(uid, subscriberList);
242         }
243
244         return getInvitationInfo(uid);
245     }
246
247     /**
248      * API to remove subscriber of invite resource
249      * 
250      * @param uid
251      *            user id
252      * @param request
253      *            received request for unsubscription
254      * 
255      * @return returns invite and invited information of the user
256      */
257     public HashMap<String, Object> removeSubscriber(String uid,
258             IRequest request) {
259
260         synchronized (mSubscribers) {
261             if (mSubscribers.containsKey(uid)) {
262
263                 mSubscribers.get(uid).removeIf(subscriber -> subscriber.mRequest
264                         .getRequestId().equals(request.getRequestId()));
265             }
266         }
267
268         return getInvitationInfo(uid);
269     }
270
271     private void notifyToSubscriber(String id) {
272
273         synchronized (mSubscribers) {
274             if (!mSubscribers.containsKey(id)) {
275                 return;
276             }
277
278             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
279             byte[] payload = cbor.encodingPayloadToCbor(getInvitationInfo(id));
280
281             for (InviteSubscriber subscriber : mSubscribers.get(id)) {
282
283                 subscriber.mSubscriber.sendResponse(
284                         MessageBuilder.createResponse(subscriber.mRequest,
285                                 ResponseStatus.CONTENT,
286                                 ContentFormat.APPLICATION_CBOR, payload));
287             }
288         }
289     }
290
291     private List<InviteTable> getInviteTableList(String property, String uid) {
292
293         InviteTable getInviteTable = new InviteTable();
294         ArrayList<InviteTable> inviteList = new ArrayList<>();
295
296         HashMap<String, Object> condition = new HashMap<>();
297         condition.put(property, uid);
298         ArrayList<HashMap<String, Object>> mapInviteList = AccountDBManager
299                 .getInstance().selectRecord(Constants.INVITE_TABLE, condition);
300         if (mapInviteList == null) {
301             throw new BadRequestException("uid is invalid");
302         }
303         for (HashMap<String, Object> mapInviteTable : mapInviteList) {
304
305             getInviteTable = mTypeInvite.convertMaptoObject(mapInviteTable,
306                     getInviteTable);
307             inviteList.add(getInviteTable);
308         }
309         return inviteList;
310
311     }
312
313 }