529eef33dc58bef942a7c1b14cc744a452434430
[iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / acl / invite / InviteManager.java
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         AccountDBManager.getInstance().deleteRecord(Constants.INVITE_TABLE,
121                 condition);
122
123         /* add user into group */
124         if (accepted) {
125
126             ArrayList<String> midlist = new ArrayList<>();
127             midlist.add(mid);
128
129             GroupManager.getInstance().addMembersToGroup(gid, midlist);
130             GroupBrokerManager.getInstance().notifyToObservers(
131                     GroupManager.getInstance().getGroupTable(gid).getMembers());
132         }
133
134         notifyToSubscriber(mid);
135         for (String uid : uidList) {
136             notifyToSubscriber(uid);
137         }
138     }
139
140     /**
141      * API to cancel invitation by user who invited member
142      * 
143      * @param uid
144      *            id of user who sent invitation
145      * @param gid
146      *            id of group to invite member to
147      * @param mid
148      *            id of invited user
149      */
150     public void cancelInvitation(String uid, String gid, String mid) {
151
152         HashMap<String, Object> condition = new HashMap<>();
153
154         condition.put(Constants.REQ_GROUP_ID, gid);
155         condition.put(Constants.KEYFIELD_INVITED_USER, mid);
156         condition.put(Constants.KEYFIELD_INVITE_USER, uid);
157
158         AccountDBManager.getInstance().deleteRecord(Constants.INVITE_TABLE,
159                 condition);
160
161         notifyToSubscriber(uid);
162         notifyToSubscriber(mid);
163     }
164
165     /**
166      * API to get invitation information
167      * 
168      * @param uid
169      *            user id
170      * 
171      * @return returns invite and invited information of the user
172      */
173     public HashMap<String, Object> getInvitationInfo(String uid) {
174         HashMap<String, Object> responsePayload = new HashMap<>();
175
176         ArrayList<Object> invitePayloadData = null;
177         ArrayList<Object> invitedPayloadData = null;
178
179         List<InviteTable> inviteList = getInviteTableList(
180                 Constants.KEYFIELD_INVITE_USER, uid);
181         if (!inviteList.isEmpty()) {
182             invitePayloadData = new ArrayList<>();
183             for (InviteTable invite : inviteList) {
184                 HashMap<String, String> inviteElement = new HashMap<>();
185                 inviteElement.put(Constants.REQ_GROUP_ID, invite.getGid());
186                 inviteElement.put(Constants.REQ_MEMBER,
187                         invite.getInvitedUser());
188                 invitePayloadData.add(inviteElement);
189             }
190         }
191
192         List<InviteTable> invitedList = getInviteTableList(
193                 Constants.KEYFIELD_INVITED_USER, uid);
194         if (!invitedList.isEmpty()) {
195             invitedPayloadData = new ArrayList<>();
196             for (InviteTable invited : invitedList) {
197                 HashMap<String, String> invitedElement = new HashMap<>();
198                 invitedElement.put(Constants.REQ_GROUP_ID, invited.getGid());
199                 invitedElement.put(Constants.REQ_MEMBER,
200                         invited.getInviteUser());
201                 invitedPayloadData.add(invitedElement);
202             }
203         }
204
205         responsePayload.put(Constants.RESP_INVITE, invitePayloadData);
206         responsePayload.put(Constants.RESP_INVITED, invitedPayloadData);
207
208         return responsePayload;
209     }
210
211     /**
212      * API to add subscriber of invite resource
213      * 
214      * @param uid
215      *            user id
216      * @param subscriber
217      *            device that sent request for subscription
218      * @param request
219      *            received request for subscription
220      * 
221      * @return returns invite and invited information of the user
222      */
223     public HashMap<String, Object> addSubscriber(String uid, Device subscriber,
224             IRequest request) {
225
226         InviteSubscriber newSubscriber = new InviteSubscriber(subscriber,
227                 request);
228
229         synchronized (mSubscribers) {
230             ArrayList<InviteSubscriber> subscriberList = mSubscribers.get(uid);
231
232             if (subscriberList == null) {
233                 subscriberList = new ArrayList<>();
234             }
235
236             subscriberList.add(newSubscriber);
237             mSubscribers.put(uid, subscriberList);
238         }
239
240         return getInvitationInfo(uid);
241     }
242
243     /**
244      * API to remove subscriber of invite resource
245      * 
246      * @param uid
247      *            user id
248      * @param request
249      *            received request for unsubscription
250      * 
251      * @return returns invite and invited information of the user
252      */
253     public HashMap<String, Object> removeSubscriber(String uid,
254             IRequest request) {
255
256         synchronized (mSubscribers) {
257             if (mSubscribers.containsKey(uid)) {
258
259                 mSubscribers.get(uid).removeIf(subscriber -> subscriber.mRequest
260                         .getRequestId().equals(request.getRequestId()));
261             }
262         }
263
264         return getInvitationInfo(uid);
265     }
266
267     private void notifyToSubscriber(String id) {
268
269         synchronized (mSubscribers) {
270             if (!mSubscribers.containsKey(id)) {
271                 return;
272             }
273
274             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
275             byte[] payload = cbor.encodingPayloadToCbor(getInvitationInfo(id));
276
277             for (InviteSubscriber subscriber : mSubscribers.get(id)) {
278
279                 subscriber.mSubscriber.sendResponse(
280                         MessageBuilder.createResponse(subscriber.mRequest,
281                                 ResponseStatus.CONTENT,
282                                 ContentFormat.APPLICATION_CBOR, payload));
283             }
284         }
285     }
286
287     private List<InviteTable> getInviteTableList(String property, String uid) {
288
289         InviteTable getInviteTable = new InviteTable();
290         ArrayList<InviteTable> inviteList = new ArrayList<>();
291
292         HashMap<String, Object> condition = new HashMap<>();
293         condition.put(property, uid);
294         ArrayList<HashMap<String, Object>> mapInviteList = AccountDBManager
295                 .getInstance().selectRecord(Constants.INVITE_TABLE, condition);
296         if (mapInviteList == null) {
297             throw new BadRequestException("uid is invalid");
298         }
299         for (HashMap<String, Object> mapInviteTable : mapInviteList) {
300
301             getInviteTable = mTypeInvite.convertMaptoObject(mapInviteTable,
302                     getInviteTable);
303             inviteList.add(getInviteTable);
304         }
305         return inviteList;
306
307     }
308
309 }