1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.openr66.database.data;
22
23 import com.fasterxml.jackson.databind.JsonNode;
24 import com.fasterxml.jackson.databind.node.ObjectNode;
25 import org.waarp.common.database.DbPreparedStatement;
26 import org.waarp.common.database.data.AbstractDbData;
27 import org.waarp.common.database.data.DbValue;
28 import org.waarp.common.database.exception.WaarpDatabaseException;
29 import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
30 import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
31 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
32 import org.waarp.common.database.model.DbModelAbstract;
33 import org.waarp.common.json.JsonHandler;
34 import org.waarp.common.logging.WaarpLogger;
35 import org.waarp.common.logging.WaarpLoggerFactory;
36 import org.waarp.openr66.dao.AbstractDAO;
37 import org.waarp.openr66.dao.DAOFactory;
38 import org.waarp.openr66.dao.exception.DAOConnectionException;
39 import org.waarp.openr66.dao.exception.DAONoDataException;
40
41 import java.sql.Types;
42 import java.util.Iterator;
43 import java.util.Map.Entry;
44
45
46
47
48 public abstract class AbstractDbDataDao<E> extends AbstractDbData {
49 private static final WaarpLogger logger =
50 WaarpLoggerFactory.getLogger(AbstractDbDataDao.class);
51 public static final String JSON_MODEL = "@model";
52 protected static final String SHOULD_NOT_BE_CALLED = "Should not be called";
53
54 protected E pojo;
55
56
57
58
59 protected AbstractDbDataDao() {
60
61 }
62
63
64
65
66
67
68
69
70 public static void validateLength(final byte[]... values)
71 throws WaarpDatabaseSqlException {
72 for (final byte[] value : values) {
73 if (value != null && value.length > DbModelAbstract.MAX_BINARY * 2) {
74 throw new WaarpDatabaseSqlException(
75 "BINARY value exceed max size: " + value.length + " (" +
76 DbModelAbstract.MAX_BINARY + ")");
77 }
78 }
79 }
80
81
82
83
84
85
86
87
88
89 public static void validateLength(final int type, final String... values)
90 throws WaarpDatabaseSqlException {
91 for (final String value : values) {
92 if (value == null) {
93 continue;
94 }
95 switch (type) {
96 case Types.VARCHAR:
97 if (value.length() > DbModelAbstract.MAX_VARCHAR) {
98 throw new WaarpDatabaseSqlException(
99 "VARCHAR value exceed max size: " + value.length() + " (" +
100 DbModelAbstract.MAX_VARCHAR + ")");
101 }
102 break;
103 case Types.NVARCHAR:
104 if (value.length() > DbModelAbstract.MAX_KEY_VARCHAR) {
105 throw new WaarpDatabaseSqlException(
106 "VARCHAR as KEY value exceed max size: " + value.length() +
107 " (" + DbModelAbstract.MAX_KEY_VARCHAR + ")");
108 }
109 break;
110 case Types.LONGVARCHAR:
111 if (value.length() > DbModelAbstract.MAX_LONGVARCHAR) {
112 throw new WaarpDatabaseSqlException(
113 "LONGVARCHAR value exceed max size: " + value.length() + " (" +
114 DbModelAbstract.MAX_LONGVARCHAR + ")");
115 }
116 break;
117 default:
118 break;
119 }
120 }
121 }
122
123 protected abstract String getTable();
124
125 protected abstract void checkValues() throws WaarpDatabaseSqlException;
126
127 protected abstract AbstractDAO<E> getDao(final boolean isCacheable)
128 throws DAOConnectionException;
129
130 protected abstract String getPrimaryKey();
131
132 protected abstract String getPrimaryField();
133
134
135
136
137
138
139 public abstract void changeUpdatedInfo(AbstractDbData.UpdatedInfo info);
140
141
142
143
144
145
146
147
148 @Override
149 public boolean exist() throws WaarpDatabaseException {
150 AbstractDAO<E> abstractDAO = null;
151 try {
152 abstractDAO = getDao(true);
153 return abstractDAO.exist(getPrimaryKey());
154 } catch (final DAOConnectionException e) {
155 throw new WaarpDatabaseNoConnectionException(e);
156 } finally {
157 DAOFactory.closeDAO(abstractDAO);
158 }
159 }
160
161
162
163
164
165
166 @Override
167 public void select() throws WaarpDatabaseException {
168 AbstractDAO<E> abstractDAO = null;
169 try {
170 abstractDAO = getDao(true);
171 pojo = abstractDAO.select(getPrimaryKey());
172 isSaved = true;
173 } catch (final DAOConnectionException e) {
174 throw new WaarpDatabaseNoConnectionException(e);
175 } catch (final DAONoDataException e) {
176 throw new WaarpDatabaseNoDataException((e));
177 } finally {
178 DAOFactory.closeDAO(abstractDAO);
179 }
180 }
181
182
183
184
185
186
187 @Override
188 public void insert() throws WaarpDatabaseException {
189 if (isSaved) {
190 return;
191 }
192 checkValues();
193 AbstractDAO<E> abstractDAO = null;
194 try {
195 abstractDAO = getDao(false);
196 abstractDAO.insert(pojo);
197 isSaved = true;
198 } catch (final DAOConnectionException e) {
199 throw new WaarpDatabaseNoConnectionException(e);
200 } finally {
201 DAOFactory.closeDAO(abstractDAO);
202 }
203 }
204
205
206
207
208
209
210 @Override
211 public void update() throws WaarpDatabaseException {
212 if (isSaved) {
213 return;
214 }
215 checkValues();
216 AbstractDAO<E> abstractDAO = null;
217 try {
218 abstractDAO = getDao(false);
219 abstractDAO.update(pojo);
220 isSaved = true;
221 } catch (final DAOConnectionException e) {
222 throw new WaarpDatabaseNoConnectionException(e);
223 } catch (final DAONoDataException e) {
224 throw new WaarpDatabaseNoDataException((e));
225 } finally {
226 DAOFactory.closeDAO(abstractDAO);
227 }
228 }
229
230
231
232
233
234
235 @Override
236 public void delete() throws WaarpDatabaseException {
237 AbstractDAO<E> abstractDAO = null;
238 try {
239 abstractDAO = getDao(false);
240 abstractDAO.delete(pojo);
241 isSaved = false;
242 } catch (final DAOConnectionException e) {
243 throw new WaarpDatabaseNoConnectionException(e);
244 } catch (final DAONoDataException e) {
245 throw new WaarpDatabaseNoDataException((e));
246 } finally {
247 DAOFactory.closeDAO(abstractDAO);
248 }
249 }
250
251
252
253
254 @Override
255 public final String asJson() {
256 final ObjectNode node = getJson();
257 return JsonHandler.writeAsString(node);
258 }
259
260
261
262
263
264 public String toJson() {
265 return JsonHandler.writeAsString(pojo);
266 }
267
268
269
270
271
272
273 @Override
274 public ObjectNode getJson() {
275 final ObjectNode node = JsonHandler.createObjectNode();
276 node.put(JSON_MODEL, getClass().getSimpleName());
277 final String json = JsonHandler.writeAsString(pojo);
278 final ObjectNode subnode = JsonHandler.getFromString(json);
279 if (subnode != null) {
280 for (final Iterator<Entry<String, JsonNode>> it = subnode.fields();
281 it.hasNext(); ) {
282 final Entry<String, JsonNode> entry = it.next();
283 node.set(entry.getKey(), entry.getValue());
284 }
285 }
286 return node;
287 }
288
289 protected abstract void setFromJson(String field, JsonNode value)
290 throws WaarpDatabaseSqlException;
291
292
293
294
295
296
297
298
299
300
301 @Override
302 public void setFromJson(final ObjectNode node, final boolean ignorePrimaryKey)
303 throws WaarpDatabaseSqlException {
304 boolean foundPrimaryKey = false;
305 for (final Iterator<Entry<String, JsonNode>> it = node.fields();
306 it.hasNext(); ) {
307 final Entry<String, JsonNode> entry = it.next();
308 logger.debug("{} = {}", entry.getKey(), entry.getValue());
309 if ("UPDATEDINFO".equalsIgnoreCase(entry.getKey())) {
310 continue;
311 }
312 if (getPrimaryField().equalsIgnoreCase(entry.getKey())) {
313 if (ignorePrimaryKey) {
314 continue;
315 } else {
316 foundPrimaryKey = !entry.getValue().isNull() &&
317 !entry.getValue().asText().isEmpty();
318 }
319 }
320 setFromJson(entry.getKey(), entry.getValue());
321 isSaved = false;
322 }
323 checkValues();
324 if (!ignorePrimaryKey && foundPrimaryKey) {
325 try {
326 insert();
327 } catch (final WaarpDatabaseException e) {
328 try {
329 update();
330 } catch (final WaarpDatabaseException ex) {
331 logger.error("Cannot save item: {}", ex.getMessage());
332 }
333 }
334 }
335 }
336
337 @Override
338 protected void initObject() {
339
340 }
341
342
343
344
345
346
347 @Override
348 protected String getWherePrimaryKey() {
349 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
350 }
351
352
353
354
355 @Override
356 protected void setPrimaryKey() {
357 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
358 }
359
360
361
362
363
364
365 @Override
366 protected String getSelectAllFields() {
367 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
368 }
369
370
371
372
373
374
375 @Override
376 protected String getInsertAllValues() {
377 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
378 }
379
380
381
382
383
384
385 @Override
386 protected String getUpdateAllFields() {
387 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
388 }
389
390
391
392
393 @Override
394 protected void setToArray() {
395 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
396 }
397
398
399
400
401 @Override
402 protected void setFromArray() {
403 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
404 }
405
406
407
408
409 @Override
410 protected void getValues(final DbPreparedStatement preparedStatement,
411 final DbValue[] values) {
412 throw new UnsupportedOperationException(SHOULD_NOT_BE_CALLED);
413 }
414 }