statistical defects fixed
[iotivity.git] / cloud / account / src / main / java / org / iotivity / cloud / accountserver / resources / acl / id / Acl.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.id;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ListIterator;
29 import java.util.UUID;
30
31 import org.iotivity.cloud.accountserver.Constants;
32 import org.iotivity.cloud.accountserver.db.AccountDBManager;
33 import org.iotivity.cloud.accountserver.db.AclTable;
34 import org.iotivity.cloud.accountserver.util.TypeCastingManager;
35 import org.iotivity.cloud.base.device.Device;
36 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
37 import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
38 import org.iotivity.cloud.base.exception.ServerException.UnAuthorizedException;
39 import org.iotivity.cloud.base.protocols.IRequest;
40 import org.iotivity.cloud.base.protocols.MessageBuilder;
41 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
42 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
43 import org.iotivity.cloud.util.Cbor;
44 import org.iotivity.cloud.util.Log;
45
46 public class Acl {
47
48     private Cbor<HashMap<String, Object>> mCbor    = new Cbor<>();
49     private String                        mAclid   = null;
50     private String                        mOid     = null;
51     private String                        mDi      = null;
52     private TypeCastingManager<AclTable>  mTypeAcl = new TypeCastingManager<>();
53
54     public Acl(String aclid) {
55         mAclid = aclid;
56     }
57
58     public Acl(String aclid, String oid, String di) {
59         mAclid = aclid;
60         mOid = oid;
61         mDi = di;
62     }
63
64     private static class AclSubscriber {
65         AclSubscriber(Device subscriber, IRequest request) {
66             mSubscriber = subscriber;
67             mRequest = request;
68         }
69
70         public Device   mSubscriber;
71         public IRequest mRequest;
72     }
73
74     private HashMap<String, AclSubscriber> mSubscribers = new HashMap<>();
75
76     public static String valueOf(Object object) {
77         return (object == null) ? "" : object.toString();
78     }
79
80     @SuppressWarnings("unchecked")
81     public static AclTable convertMaptoAclObject(
82             HashMap<String, Object> aclMap) {
83         AclTable aclTable = new AclTable();
84         try {
85             aclTable.setAclid(valueOf(aclMap.get(Constants.KEYFIELD_ACLID)));
86             aclTable.setDi(valueOf(aclMap.get(Constants.KEYFIELD_DI)));
87             aclTable.setOid(valueOf(aclMap.get(Constants.REQ_OWNER_ID)));
88             aclTable.setRowneruuid(
89                     valueOf(aclMap.get(Constants.REQ_ROWNER_ID)));
90
91             List<Ace> aceList = new ArrayList<Ace>();
92
93             List<HashMap<String, Object>> aclist = (List<HashMap<String, Object>>) aclMap
94                     .get(Constants.REQ_ACL_LIST);
95
96             if (aclist == null) {
97                 return aclTable;
98             }
99
100             for (HashMap<String, Object> eachAce : aclist) {
101
102                 Ace ace = new Ace();
103
104                 ace.setAceid(valueOf(eachAce.get(Constants.REQ_ACE_ID)));
105                 ace.setSubjectuuid(valueOf(
106                         eachAce.get(Constants.KEYFIELD_ACE_SUBJECT_ID)));
107                 ace.setStype(Integer.valueOf(eachAce
108                         .get(Constants.KEYFIELD_ACE_SUBJECT_TYPE).toString()));
109                 ace.setPermission(Integer.valueOf(eachAce
110                         .get(Constants.KEYFIELD_ACE_PERMISSION).toString()));
111
112                 Object validity = eachAce.get(Constants.KEYFIELD_ACE_VALIDITY);
113                 if (validity != null) {
114                     ace.setValidity((List<String>) validity);
115                 }
116
117                 List<AceResource> resourceLst = new ArrayList<AceResource>();
118                 List<HashMap<String, Object>> resourceList = (List<HashMap<String, Object>>) eachAce
119                         .get(Constants.KEYFIELD_ACE_RESOURCE);
120                 for (HashMap<String, Object> resrouce : resourceList) {
121
122                     AceResource aceResource = new AceResource();
123                     aceResource.setHref(valueOf(resrouce
124                             .get(Constants.KEYFIELD_ACE_RESOURCE_HREF)));
125                     List<String> rtList = (List<String>) resrouce
126                             .get(Constants.KEYFIELD_ACE_RESOURCE_RT);
127                     aceResource.setRt(rtList);
128                     List<String> ifList = (List<String>) resrouce
129                             .get(Constants.KEYFIELD_ACE_RESOURCE_IF);
130                     aceResource.setOicif(ifList);
131
132                     resourceLst.add(aceResource);
133                 }
134                 ace.setResources(resourceLst);
135
136                 aceList.add(ace);
137
138             }
139             aclTable.setAclist(aceList);
140         } catch (Exception e) {
141             throw new InternalServerErrorException(
142                     "Map to Acl Object casting error " + e.getMessage());
143         }
144         return aclTable;
145
146     }
147
148     @SuppressWarnings("unchecked")
149
150     public List<HashMap<String, Object>> addACE(
151             List<HashMap<String, Object>> aclist) {
152         Log.v("IN addACE");
153         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
154                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
155         if (hashmap == null) {
156             throw new BadRequestException("aclid is invalid");
157         }
158         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
159                 .get(Constants.REQ_ACL_LIST);
160
161         ListIterator<HashMap<String, Object>> iterator = aclist.listIterator();
162         while (iterator.hasNext()) {
163             HashMap<String, Object> aceMap = iterator.next();
164             if (aceMap.get(Constants.KEYFIELD_ACE_SUBJECT_ID)
165                     .equals(hashmap.get(Constants.REQ_OWNER_ID))) {
166                 // remove current iterator
167                 iterator.remove();
168                 continue;
169             }
170             aceMap.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString());
171         }
172
173         List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
174                 aclist);
175
176         if (aclDbList != null) {
177             newAcList.addAll(aclDbList);
178         }
179         hashmap.put(Constants.REQ_ACL_LIST, newAcList);
180         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
181                 hashmap);
182         notifyToSubscriber(getResponsePayload(true));
183         Log.v("OUT addACE");
184         return aclist;
185     }
186
187     public HashMap<String, Object> getACE(String aceid) {
188         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
189                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
190         if (hashmap == null) {
191             throw new BadRequestException("aclid is invalid");
192         }
193
194         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
195                 .get(Constants.REQ_ACL_LIST);
196         ListIterator<HashMap<String, Object>> iterator = aclDbList
197                 .listIterator();
198         while (iterator.hasNext()) {
199             HashMap<String, Object> aceMap = iterator.next();
200             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
201                 // Return the current element from the iterator
202                 return aceMap;
203             }
204         }
205         throw new BadRequestException("aceid is invalid");
206     }
207
208     public boolean isValidAceId(String aceid) {
209         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
210                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
211         if (hashmap == null) {
212             return false;
213         }
214
215         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
216                 .get(Constants.REQ_ACL_LIST);
217         ListIterator<HashMap<String, Object>> iterator = aclDbList
218                 .listIterator();
219         while (iterator.hasNext()) {
220             HashMap<String, Object> aceMap = iterator.next();
221             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
222                 return true;
223             }
224         }
225         return false;
226     }
227
228     public void updateACE(String aceid, HashMap<String, Object> ace) {
229         Log.v("IN updateACE");
230
231         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
232                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
233
234         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
235                 .get(Constants.REQ_ACL_LIST);
236
237         ace.put(Constants.REQ_ACE_ID, aceid);
238
239         ListIterator<HashMap<String, Object>> iterator = aclDbList
240                 .listIterator();
241         while (iterator.hasNext()) {
242             HashMap<String, Object> aceMap = iterator.next();
243             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
244                 // replace current iterator with new element
245                 iterator.set(ace);
246                 break;
247             }
248         }
249
250         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
251         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
252                 hashmap);
253         notifyToSubscriber(getResponsePayload(true));
254         Log.v("OUT updateACE");
255
256     }
257
258     public void deleteACE(String aceid) {
259
260         HashMap<String, Object> hashmap = AccountDBManager.getInstance()
261                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
262
263         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
264                 .get(Constants.REQ_ACL_LIST);
265
266         ListIterator<HashMap<String, Object>> iterator = aclDbList
267                 .listIterator();
268         while (iterator.hasNext()) {
269             HashMap<String, Object> aceMap = iterator.next();
270             if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
271                 // Remove the current element from the iterator
272                 iterator.remove();
273                 break;
274             }
275         }
276
277         hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
278         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
279                 hashmap);
280         notifyToSubscriber(getResponsePayload(true));
281     }
282
283     public void deleteAclist() {
284         AclTable aclTable = getAclTable();
285         aclTable.setAclist(null);
286         AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
287                 mTypeAcl.convertObjectToMap(aclTable));
288         notifyToSubscriber(getResponsePayload(true));
289     }
290
291     public HashMap<String, Object> getInfo() {
292         return getResponsePayload(true);
293     }
294
295     public HashMap<String, Object> addSubscriber(String di, Device subscriber,
296             IRequest request) {
297
298         verifyAclTableDi(di);
299         AclSubscriber newSubscriber = new AclSubscriber(subscriber, request);
300         mSubscribers.put(di, newSubscriber);
301         return getInfo();
302     }
303
304     public HashMap<String, Object> removeSubscriber(String di) {
305
306         HashMap<String, Object> responsePayload = getResponsePayload(true);
307         if (mSubscribers.containsKey(di)) {
308             mSubscribers.remove(di);
309         }
310         return responsePayload;
311     }
312
313     private void verifyAclTableDi(String di) {
314         AclTable aclTable = getAclTable();
315         if (aclTable.getDi() == null) {
316             throw new BadRequestException("di is invalid in Acl");
317         }
318         String mDi = aclTable.getDi();
319         if (!mDi.equals(di)) {
320             throw new UnAuthorizedException(
321                     di + "is not Device ID of this ACL");
322         }
323     }
324
325     private void notifyToSubscriber(
326             HashMap<String, Object> notifyBytePayloadData) {
327         synchronized (mSubscribers) {
328
329             Iterator<String> iterator = mSubscribers.keySet().iterator();
330             while (iterator.hasNext()) {
331                 String key = iterator.next();
332                 AclSubscriber aclSubscriber = mSubscribers.get(key);
333                 aclSubscriber.mSubscriber.sendResponse(
334                         MessageBuilder.createResponse(aclSubscriber.mRequest,
335                                 ResponseStatus.CONTENT,
336                                 ContentFormat.APPLICATION_CBOR,
337                                 mCbor.encodingPayloadToCbor(
338                                         notifyBytePayloadData)));
339             }
340         }
341     }
342
343     private AclTable getAclTable() {
344         AclTable getAclTable = new AclTable();
345         getAclTable = convertMaptoAclObject(AccountDBManager.getInstance()
346                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0));
347         return getAclTable;
348     }
349
350     private HashMap<String, Object> getAclTablePayLoad() {
351         HashMap<String, Object> aclPayload = new HashMap<>();
352         aclPayload = AccountDBManager.getInstance()
353                 .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
354         return aclPayload;
355     }
356
357     private HashMap<String, Object> getResponsePayload(boolean isAliveAcl) {
358         return isAliveAcl ? getAclTablePayLoad() : null;
359     }
360
361     private HashMap<String, Object> getCondition() {
362         HashMap<String, Object> condition = new HashMap<>();
363         condition.put(Constants.REQ_ACL_ID, mAclid);
364         return condition;
365     }
366
367 }