Extend user settings API
[ccsdk/features.git] / sdnr / wt / data-provider / dblib / src / main / java / org / onap / ccsdk / features / sdnr / wt / dataprovider / database / sqldb / data / HtUserdataManagerBase.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
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  * ============LICENSE_END=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.database.sqldb.data;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.nio.file.Files;
27 import org.json.JSONArray;
28 import org.json.JSONException;
29 import org.json.JSONObject;
30 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.HtUserdataManager;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 public abstract class HtUserdataManagerBase implements HtUserdataManager {
35
36     private static final Logger LOG = LoggerFactory.getLogger(HtUserdataManagerBase.class);
37
38     private static final String USERDATA_DEFAULTS_FILENAME = "etc/userdata-defaults.json";
39     private static final JSONObject USERDATA_DEFAULTS_CONTENT = loadDefaults();
40
41     protected static JSONObject loadDefaults() {
42         File f = new File(USERDATA_DEFAULTS_FILENAME);
43         String content;
44         JSONObject o = null;
45         if (f.exists()) {
46             try {
47                 content = Files.readString(f.toPath());
48                 o = new JSONObject(content);
49             } catch (IOException e) {
50                 LOG.warn("problem loading defaults: ", e);
51             } catch (JSONException e) {
52                 LOG.warn("problem parsing defaults: ", e);
53             }
54         }
55         return o;
56     }
57
58     protected abstract String readUserdata(String username, String defaultValue);
59
60     @Override
61     public String getUserdata(String username) {
62         String json = this.readUserdata(username, "{}");
63         if (USERDATA_DEFAULTS_CONTENT != null) {
64             JSONObject merge = mergeData(new JSONObject(json), USERDATA_DEFAULTS_CONTENT);
65             json = merge.toString();
66         }
67         return json;
68     }
69
70     @Override
71     public String getUserdata(String username, String key) {
72         final String EMPTY_JSON_OBJECT = "{}";
73         JSONObject o = new JSONObject(this.getUserdata(username));
74         if(key==null || !key.contains("."))
75             return o.has(key) ? o.get(key).toString() : EMPTY_JSON_OBJECT;
76         final String[] keys = key.split("\\.");
77         Object tmp;
78         for (int i=0;i<keys.length-1;i++){
79             if(!o.has(keys[i])){
80                 return EMPTY_JSON_OBJECT;
81             }
82             tmp = o.get(keys[i]);
83             if(!(tmp instanceof JSONObject)) {
84                 return EMPTY_JSON_OBJECT;
85             }
86             o = (JSONObject)tmp;
87         }
88         tmp= o.has(keys[keys.length-1])? o.get(keys[keys.length-1]):EMPTY_JSON_OBJECT;
89         if(tmp instanceof JSONObject){
90             return ((JSONObject)tmp).toString();
91         }
92         if(tmp instanceof JSONArray){
93             return ((JSONArray)tmp).toString();
94         }
95         if( tmp instanceof String){
96             return String.format("\"%s\"",tmp);
97         }
98         return String.valueOf(tmp);
99     }
100
101     @Override
102     public boolean setUserdata(String username, String key, String data) {
103         if(key == null || data == null){
104             return false;
105         }
106         JSONObject o = new JSONObject(this.getUserdata(username));
107         if(!key.contains(".")) {
108             o.put(key, new JSONObject(data));
109         }
110         else{
111             final String[] keys = key.split("\\.");
112             JSONObject tmp = o;
113             Object tmpObject;
114             for(int i=0;i<keys.length-1;i++){
115                 if(!tmp.has(keys[i])){
116                     tmp.put(keys[i], new JSONObject());
117                 }
118                 tmpObject = tmp.get(keys[i]);
119                  if(!(tmpObject instanceof JSONObject)){
120                     return false;
121                 }
122                 tmp = (JSONObject) tmpObject;
123             }
124             if(data.startsWith("{")){
125                 tmp.put(keys[keys.length-1], new JSONObject(data));
126             }
127             else if (data.startsWith("[")){
128                 tmp.put(keys[keys.length-1], new JSONArray(data));
129             }
130             else if(data.startsWith("\"") && data.endsWith("\"")){
131                 tmp.put(keys[keys.length-1],data.substring(1,data.length()-1));
132             }
133             else if("true".equals(data) || "false".equals(data)){
134                 tmp.put(keys[keys.length-1],"true".equals(data));
135             }
136             else {
137                 try {
138                     tmp.put(keys[keys.length - 1], Double.parseDouble(data));
139                 } catch (NumberFormatException e) {
140                     return false;
141                 }
142             }
143         }
144         return this.setUserdata(username, o.toString());
145     }
146
147     @Override
148     public boolean removeUserdata(String username, String key) {
149         if(key == null){
150             return false;
151         }
152         JSONObject o = new JSONObject(this.getUserdata(username));
153         if(!key.contains(".")) {
154             if (o.has(key)) {
155                 o.remove(key);
156                 return this.setUserdata(username, o.toString());
157             }
158         }
159         else {
160             final String[] keys = key.split("\\.");
161             JSONObject tmp = o;
162             Object tmpObject;
163             for(int i=0;i<keys.length-1;i++){
164                 if(!tmp.has(keys[i])){
165                     return false;
166                 }
167                 tmpObject = tmp.get(keys[i]);
168                 if(!(tmpObject instanceof JSONObject)){
169                     return false;
170                 }
171                 tmp = (JSONObject) tmpObject;
172             }
173             if(!tmp.has(keys[keys.length-1])){
174                 return false;
175             }
176             tmp.remove(keys[keys.length-1]);
177             return this.setUserdata(username, o.toString());
178
179         }
180         return false;
181     }
182
183     protected static JSONObject mergeData(JSONObject o, String key, JSONObject subObject) {
184         if (!o.has(key)) {
185             o.put(key, subObject);
186         } else {
187             JSONObject tmp = new JSONObject();
188             tmp.put(key, subObject);
189             o = mergeData(tmp, o);
190         }
191         return o;
192     }
193
194     protected static JSONObject mergeData(JSONObject source, JSONObject target) throws JSONException {
195         String[] keys = JSONObject.getNames(source);
196         if (keys == null) {
197             return target;
198         }
199         for (String key : keys) {
200             Object value = source.get(key);
201             if (!target.has(key)) {
202                 // new value for "key":
203                 target.put(key, value);
204             } else {
205                 // existing value for "key" - recursively deep merge:
206                 if (value instanceof JSONObject) {
207                     JSONObject valueJson = (JSONObject) value;
208                     mergeData(valueJson, target.getJSONObject(key));
209                 } else {
210                     target.put(key, value);
211                 }
212             }
213         }
214         return target;
215     }
216
217 }