Merge branch 'cloud-interface'
[iotivity.git] / cloud / resourcedirectory / src / main / java / org / iotivity / cloud / rdserver / resources / directory / RDManager.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.rdserver.resources.directory;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27
28 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
29 import org.iotivity.cloud.rdserver.Constants;
30 import org.iotivity.cloud.rdserver.db.DBManager;
31 import org.iotivity.cloud.rdserver.resources.directory.rd.InsManager;
32 import org.iotivity.cloud.util.Log;
33
34 /**
35  * 
36  * This class provides a set of APIs handle requests about resource information
37  *
38  */
39 public class RDManager {
40
41     private InsManager                         mInsManager       = new InsManager();
42     private PayloadManager                     mPayloadManager   = new PayloadManager();
43
44     private ArrayList<HashMap<String, Object>> mResourcePresence = new ArrayList<>();
45
46     /**
47      * API for handling resource-publish process
48      * 
49      * @param requestPayload
50      *            request payload
51      * @return response payload
52      */
53     public HashMap<String, Object> publishResource(
54             HashMap<String, Object> requestPayload) {
55
56         HashMap<String, Object> deviceInfo = setResourceDeviceInfo(
57                 requestPayload);
58         ArrayList<HashMap<String, Object>> links = getLinks(requestPayload);
59
60         // check ins and set ins
61         setResourceIns(deviceInfo.get(Constants.DEVICE_ID).toString(), links);
62
63         storeResource(links, deviceInfo);
64
65         return requestPayload;
66
67     }
68
69     // set di, n, lt info
70     private HashMap<String, Object> setResourceDeviceInfo(
71             HashMap<String, Object> payload) {
72         return mPayloadManager.setPayloadData(payload,
73                 mPayloadManager.pubTagKey);
74     }
75
76     private ArrayList<HashMap<String, Object>> getLinks(
77             HashMap<String, Object> requestPayload) {
78         return (ArrayList<HashMap<String, Object>>) requestPayload
79                 .get(Constants.LINKS);
80
81     }
82
83     private void storeResource(ArrayList<HashMap<String, Object>> links,
84             HashMap<String, Object> deviceInfo) {
85
86         ArrayList<HashMap<String, Object>> resourcePresence = new ArrayList<>();
87
88         for (HashMap<String, Object> link : links) {
89             HashMap<String, Object> storeInfo = new HashMap<>();
90             HashMap<String, Object> storeLink = mPayloadManager
91                     .setPayloadData(link, mPayloadManager.pubLinkKey);
92             mPayloadManager.changePolicyTypeToStore(storeLink);
93             storeInfo.putAll(storeLink);
94             storeInfo.putAll(deviceInfo);
95             storeResourceInDB(storeInfo);
96             resourcePresence.add(storeInfo);
97         }
98         setmResourcePresence(resourcePresence);
99
100     }
101
102     private void storeResourceInDB(HashMap<String, Object> rdInfo) {
103         HashMap<String, Object> condition = new HashMap<>();
104         condition.put(Constants.DEVICE_ID, rdInfo.get(Constants.DEVICE_ID));
105         condition.put(Constants.INS, rdInfo.get(Constants.INS));
106         if (checkResourceExist(condition).isEmpty()) {
107             DBManager.getInstance().insertRecord(Constants.RD_TABLE, rdInfo);
108             // set resource presence
109             rdInfo.put(Constants.TRIGGER, Constants.RES_CREATE);
110         } else {
111             DBManager.getInstance().insertAndReplaceRecord(Constants.RD_TABLE,
112                     rdInfo);
113             rdInfo.put(Constants.TRIGGER, Constants.RES_CHANGE);
114         }
115
116     }
117
118     private void setResourceIns(String di,
119             ArrayList<HashMap<String, Object>> links) {
120
121         for (HashMap<String, Object> link : links) {
122             String href = link.get(Constants.HREF).toString();
123             int ins = (int) link.get(Constants.INS);
124             int newIns = checkResourceIns(di, href, ins);
125             if (newIns == -1) {
126                 throw new BadRequestException("resource ins is not correct");
127             }
128             link.put(Constants.INS, newIns);
129         }
130     }
131
132     private int checkResourceIns(String di, String href, int ins) {
133         int storedIns = mInsManager.getIns(di, href);
134         if (ins == 0) {
135             if (storedIns == -1) {
136                 // create ins
137                 ins = mInsManager.createIns(di);
138             } else {
139                 ins = storedIns;
140             }
141         } else {
142             if (ins != storedIns) {
143                 ins = -1;
144             }
145         }
146         return ins;
147     }
148
149     /**
150      * API for handling resource-delete process
151      * 
152      * @param di
153      *            device id
154      * @param ins
155      *            unique id of resource
156      */
157     public void deleteResource(String di, List<String> insList) {
158
159         HashMap<String, Object> condition = new HashMap<>();
160         condition.put(Constants.DEVICE_ID, di);
161
162         ArrayList<HashMap<String, Object>> foundRecord = new ArrayList<>();
163
164         if (insList == null) {
165             foundRecord = checkResourceExist(condition);
166             DBManager.getInstance().deleteRecord(Constants.RD_TABLE, condition);
167         } else {
168             for (String ins : insList) {
169                 condition.put(Constants.INS, Integer.parseInt(ins));
170                 if (!checkResourceExist(condition).isEmpty()) {
171                     foundRecord.add(checkResourceExist(condition).get(0));
172                     DBManager.getInstance().deleteRecord(Constants.RD_TABLE,
173                             condition);
174                 }
175             }
176         }
177
178         if (!foundRecord.isEmpty()) {
179             // set resource presence
180             for (HashMap<String, Object> record : foundRecord) {
181                 record.put(Constants.TRIGGER, Constants.RES_DELETE);
182             }
183             setmResourcePresence(foundRecord);
184         }
185     }
186
187     private ArrayList<HashMap<String, Object>> checkResourceExist(
188             HashMap<String, Object> condition) {
189         ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
190                 .selectRecord(Constants.RD_TABLE, condition);
191
192         return records;
193     }
194
195     /**
196      * API for handling resource-discover process
197      * 
198      * @param diList
199      *            list of device id
200      * @param rtList
201      *            list of resource type
202      * @param ifList
203      *            list of resource interface
204      * @return response payload
205      */
206     public ArrayList<Object> discoverResource(List<String> diList,
207             List<String> rtList, List<String> ifList) {
208
209         HashMap<String, Object> condition = new HashMap<>();
210
211         ArrayList<Object> response = new ArrayList<>();
212
213         if (diList == null) {
214             return response;
215         }
216
217         if (rtList == null && ifList == null) {
218             readResource(diList, condition, response);
219         }
220
221         if (rtList != null) {
222             for (String rt : rtList) {
223                 condition.put(Constants.RESOURCE_TYPE, rt);
224                 readResource(diList, condition, response);
225             }
226         }
227
228         if (ifList != null) {
229             for (String itf : ifList) {
230                 condition.put(Constants.INTERFACE, itf);
231                 readResource(diList, condition, response);
232             }
233         }
234
235         Log.d("discovery payload : " + response);
236
237         return response;
238     }
239
240     private void readResource(List<String> diList,
241             HashMap<String, Object> condition, ArrayList<Object> response) {
242
243         ArrayList<String> onDiList = getPresenceOnDevices(diList);
244
245         for (String di : onDiList) {
246             condition.put(Constants.DEVICE_ID, di);
247             ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
248                     .selectRecord(Constants.RD_TABLE, condition);
249
250             if (!records.isEmpty()) {
251                 response.add(makeDiscoverResponseSegment(records));
252             }
253
254         }
255     }
256
257     private ArrayList<String> getPresenceOnDevices(List<String> diList) {
258         ArrayList<String> onDiList = new ArrayList<>();
259         HashMap<String, Object> condition = new HashMap<>();
260
261         for (String di : diList) {
262             condition.put(Constants.DEVICE_ID, di);
263             HashMap<String, Object> record = DBManager.getInstance()
264                     .selectOneRecord(Constants.PRESENCE_TABLE, condition);
265
266             if (!record.isEmpty() && record.get(Constants.PRESENCE_STATE)
267                     .equals(Constants.PRESENCE_ON)) {
268                 onDiList.add(di);
269             }
270
271         }
272         return onDiList;
273     }
274
275     private HashMap<String, Object> makeDiscoverResponseSegment(
276             ArrayList<HashMap<String, Object>> records) {
277
278         HashMap<String, Object> responseSegment = new HashMap<>();
279
280         // make Tags
281         HashMap<String, Object> discoverTag = mPayloadManager
282                 .setPayloadData(records.get(0), mPayloadManager.discoverTagKey);
283         responseSegment.putAll(discoverTag);
284
285         ArrayList<Object> links = new ArrayList<>();
286         // make links
287         for (HashMap<String, Object> record : records) {
288             HashMap<String, Object> link = mPayloadManager
289                     .setPayloadData(record, mPayloadManager.discoverLinkKey);
290             mPayloadManager.changePolicyTypeToDiscover(link);
291             links.add(link);
292         }
293         responseSegment.put(Constants.LINKS, links);
294
295         return responseSegment;
296
297     }
298
299     private void setmResourcePresence(
300             ArrayList<HashMap<String, Object>> resourcePresence) {
301         this.mResourcePresence = resourcePresence;
302     }
303
304     /**
305      * API for getting resource information to notify
306      * 
307      * @return resource information
308      */
309     public ArrayList<HashMap<String, Object>> getmResourcePresence() {
310         return mResourcePresence;
311     }
312
313 }