blob: 4b14b42b7f3e74f0aee8cc0a7b0eff49b2dcfd39 [file] [log] [blame]
Michael Hanl1fdc5df2016-06-08 12:17:49 +02001package de.ids_mannheim.korap.user;
2
3import com.fasterxml.jackson.databind.JsonNode;
4import com.fasterxml.jackson.databind.node.ArrayNode;
5import com.fasterxml.jackson.databind.node.ObjectNode;
6import de.ids_mannheim.korap.exceptions.KustvaktException;
7import de.ids_mannheim.korap.exceptions.StatusCodes;
Michael Hanlc0ed00f2016-06-23 14:33:10 +02008import de.ids_mannheim.korap.interfaces.ValidatorIface;
Michael Hanl1fdc5df2016-06-08 12:17:49 +02009import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
10import de.ids_mannheim.korap.utils.JsonUtils;
11
Michael Hanlc0ed00f2016-06-23 14:33:10 +020012import java.io.IOException;
Michael Hanl1fdc5df2016-06-08 12:17:49 +020013import java.util.*;
14
15/**
16 * @author hanl
17 * @date 27/01/2016
18 */
19public abstract class DataFactory {
20
21 private static final Map<Class<? extends Userdata>, UserDataDbIface> instances = new HashMap<>();
22
23 private static DataFactory factory;
24
25
26 private DataFactory () {}
27
28
29 public static DataFactory getFactory () {
30 if (factory == null)
31 factory = new DefaultFactory();
32 return factory;
33 }
34
35
36 /**
37 * if data string null, returns an empty data holding object
38 *
39 * @param data
40 * @return
41 */
42 public abstract Object convertData (String data);
43
44
45 public abstract int size (Object data);
46
47
48 public abstract Set<String> keys (Object data);
49
50
51 public abstract Collection<Object> values (Object data);
52
margaretha7e16d6f2017-04-18 18:01:59 +020053 public abstract Object validate(Object data, ValidatorIface validator) throws KustvaktException;
Michael Hanl1fdc5df2016-06-08 12:17:49 +020054
55 @Deprecated
56 public abstract Map<String, Object> fields (Object data);
57
58
59 public abstract Object getValue (Object data, String pointer);
60
61
62 public abstract boolean addValue (Object data, String field, Object value);
63
64
65 public abstract boolean removeValue (Object data, String field);
66
67
margarethad4796662017-11-09 16:11:40 +010068 public abstract String toStringValue (Object data) throws KustvaktException;
Michael Hanl1fdc5df2016-06-08 12:17:49 +020069
Michael Hanl2de64112016-07-02 17:13:34 +020070 public abstract Object filter(Object data, String ... keys);
Michael Hanl1fdc5df2016-06-08 12:17:49 +020071
72 public boolean checkDataType (Object data) {
73 throw new RuntimeException("Wrong data type for factory setting!");
74 }
75
76
77 /**
78 * updates data1 with values from data2
79 *
80 * @param data1
81 * data object that needs update
82 * @param data2
83 * values that update data1
84 * @return
85 */
86 public abstract Object merge (Object data1, Object data2);
87
88
89
90 private static class DefaultFactory extends DataFactory {
91
92 @Override
93 public Object convertData (String data) {
94 if (data == null)
95 return JsonUtils.createObjectNode();
margaretha894a7d72017-11-08 19:24:20 +010096 try {
97 return JsonUtils.readTree(data);
98 }
99 catch (KustvaktException e) {
100 return null;
101 }
Michael Hanl1fdc5df2016-06-08 12:17:49 +0200102 }
103
104
105 @Override
106 public int size (Object data) {
107 if (checkDataType(data))
108 return ((JsonNode) data).size();
109 return -1;
110 }
111
112
113 @Override
114 public Set<String> keys (Object data) {
115 Set<String> keys = new HashSet<>();
116 if (checkDataType(data) && ((JsonNode) data).isObject()) {
117 Iterator it = ((JsonNode) data).fieldNames();
118 while (it.hasNext())
119 keys.add((String) it.next());
120 }
121 return keys;
122 }
123
124
125 @Override
126 public Collection<Object> values (Object data) {
127 return new HashSet<>();
128 }
129
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200130 @Override
margaretha7e16d6f2017-04-18 18:01:59 +0200131 public Object validate(Object data, ValidatorIface validator) throws KustvaktException {
Michael Hanlc0ed00f2016-06-23 14:33:10 +0200132 if (checkDataType(data) && ((JsonNode) data).isObject()) {
133 try {
134 Map mdata = JsonUtils.read(toStringValue(data), HashMap.class);
135 return validator.validateMap(mdata);
136 } catch (IOException e) {
137 // do nothing
138 }
139 }
140 return JsonUtils.createObjectNode();
141 }
142
Michael Hanl1fdc5df2016-06-08 12:17:49 +0200143
144 @Override
145 public Map<String, Object> fields (Object data) {
146 return new HashMap<>();
147 }
148
149
150 @Override
151 public Object getValue (Object data, String key) {
152 if (checkDataType(data)) {
153 JsonNode value;
154 if (key.startsWith("/"))
155 value = ((JsonNode) data).at(key);
156 else
157 value = ((JsonNode) data).path(key);
158
159 if (value.canConvertToInt())
160 return value.asInt();
161 else if (value.isBoolean())
162 return value.asBoolean();
163 else if (value.isTextual())
164 return value.asText();
165 }
166 return null;
167 }
168
169
170 //fixme: test that this works with different types
171 @Override
172 public boolean addValue (Object data, String field, Object value) {
173 if (checkDataType(data)) {
174 if (((JsonNode) data).isObject()) {
175 ObjectNode node = (ObjectNode) data;
176 if (value instanceof String)
177 node.put(field, (String) value);
178 if (value instanceof Boolean)
179 node.put(field, (Boolean) value);
180 if (value instanceof Integer)
181 node.put(field, (Integer) value);
182 if (value instanceof JsonNode)
183 node.put(field, (JsonNode) value);
184 return true;
185 }
186 else if (((JsonNode) data).isArray()) {
187 ArrayNode node = (ArrayNode) data;
188 if (value instanceof String)
189 node.add((String) value);
190 if (value instanceof Boolean)
191 node.add((Boolean) value);
192 if (value instanceof Integer)
193 node.add((Integer) value);
194 return true;
195 }
196 }
197 return false;
198 }
199
200
201 @Override
202 public boolean removeValue (Object data, String field) {
203 if (checkDataType(data) && ((JsonNode) data).isObject()) {
204 ObjectNode node = (ObjectNode) data;
205 node.remove(field);
206 return true;
207 }
208 return false;
209 }
210
211
212 @Override
margarethad4796662017-11-09 16:11:40 +0100213 public String toStringValue (Object data) throws KustvaktException {
Michael Hanl1fdc5df2016-06-08 12:17:49 +0200214 if (data instanceof JsonNode)
215 return JsonUtils.toJSON(data);
216 return data.toString();
217 }
218
Michael Hanl2de64112016-07-02 17:13:34 +0200219 @Override
220 public Object filter(Object data, String... keys) {
221 if (checkDataType(data) && ((JsonNode) data).isObject()) {
222 ObjectNode node = ((JsonNode) data).deepCopy();
223 return node.retain(keys);
224 }
225 return JsonUtils.createObjectNode();
226 }
227
Michael Hanl1fdc5df2016-06-08 12:17:49 +0200228
229 @Override
230 public boolean checkDataType (Object data) {
231 if (!(data instanceof JsonNode))
232 super.checkDataType(data);
233 return true;
234 }
235
236
237 @Override
238 public Object merge (Object data1, Object data2) {
239 if (checkDataType(data1) && checkDataType(data2)) {
240 if (((JsonNode) data1).isObject()
241 && ((JsonNode) data2).isObject()) {
242 ((ObjectNode) data1).putAll((ObjectNode) data2);
243 }
244 else if (((JsonNode) data1).isArray()
245 && ((JsonNode) data2).isArray()) {
246 ((ArrayNode) data1).addAll((ArrayNode) data2);
247 }
248 }
249 return data1;
250 }
251
252 }
253}