1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.admin.common;
22
23 import java.io.Serializable;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.util.Formatter;
28 import java.util.Locale;
29 import java.util.UUID;
30
31 import org.efaps.db.Context;
32 import org.efaps.db.transaction.ConnectionResource;
33 import org.efaps.db.wrapper.SQLPart;
34 import org.efaps.db.wrapper.SQLSelect;
35 import org.efaps.util.EFapsException;
36 import org.efaps.util.cache.CacheLogListener;
37 import org.efaps.util.cache.CacheObjectInterface;
38 import org.efaps.util.cache.CacheReloadException;
39 import org.efaps.util.cache.InfinispanCache;
40 import org.infinispan.Cache;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50 public final class NumberGenerator
51 implements CacheObjectInterface, Serializable
52 {
53
54
55
56
57 private static final long serialVersionUID = 1L;
58
59
60
61
62
63 private static final String SQL_ID = new SQLSelect()
64 .column(0, "ID")
65 .column(1, "NAME")
66 .column(1, "UUID")
67 .column(0, "FORMAT")
68 .from("T_CMNUMGEN", 0)
69 .leftJoin("T_CMABSTRACT", 1, "ID", 0, "ID")
70 .addPart(SQLPart.WHERE).addColumnPart(0, "ID").addPart(SQLPart.EQUAL).addValuePart("?").toString();
71
72
73
74
75
76 private static final String SQL_NAME = new SQLSelect()
77 .column(0, "ID")
78 .column(1, "NAME")
79 .column(1, "UUID")
80 .column(0, "FORMAT")
81 .from("T_CMNUMGEN", 0)
82 .leftJoin("T_CMABSTRACT", 1, "ID", 0, "ID")
83 .addPart(SQLPart.WHERE).addColumnPart(1, "NAME").addPart(SQLPart.EQUAL).addValuePart("?")
84 .toString();
85
86
87
88
89
90 private static final String SQL_UUID = new SQLSelect()
91 .column(0, "ID")
92 .column(1, "NAME")
93 .column(1, "UUID")
94 .column(0, "FORMAT")
95 .from("T_CMNUMGEN", 0)
96 .leftJoin("T_CMABSTRACT", 1, "ID", 0, "ID")
97 .addPart(SQLPart.WHERE).addColumnPart(1, "UUID").addPart(SQLPart.EQUAL).addValuePart("?")
98 .toString();
99
100
101
102
103 private static final String UUIDCACHE = NumberGenerator.class.getName() + ".UUID";
104
105
106
107
108 private static final String IDCACHE = NumberGenerator.class.getName() + ".ID";
109
110
111
112
113 private static final String NAMECACHE = NumberGenerator.class.getName() + ".Name";
114
115
116
117
118 private static final Logger LOG = LoggerFactory.getLogger(NumberGenerator.class);
119
120
121
122
123 private static final String NAME_PREFIX = "numgen_";
124
125
126
127
128 private static final String NAME_SUFFIX = "_seq";
129
130
131
132
133 private final long id;
134
135
136
137
138 private final String name;
139
140
141
142
143 private final UUID uuid;
144
145
146
147
148 private final String format;
149
150
151
152
153
154
155
156 private NumberGenerator(final long _id,
157 final String _name,
158 final String _uuid,
159 final String _format)
160 {
161 this.id = _id;
162 this.name = _name;
163 this.uuid = UUID.fromString(_uuid);
164 this.format = _format;
165 }
166
167
168
169
170
171
172 public String getDBName()
173 {
174 return NumberGenerator.NAME_PREFIX + this.id + NumberGenerator.NAME_SUFFIX;
175 }
176
177
178
179
180
181
182
183
184 public String getNextVal()
185 throws EFapsException
186 {
187 return getNextVal(new Object[0]);
188 }
189
190
191
192
193
194
195
196
197
198 public String getNextVal(final Object... _args)
199 throws EFapsException
200 {
201 final Object[] args = new Object[_args.length + 1];
202 try {
203 final long val = Context.getDbType().nextSequence(Context.getThreadContext().getConnection(), getDBName());
204 args[0] = val;
205 } catch (final SQLException e) {
206 throw new EFapsException(NumberGenerator.class, " getNextVal()", e);
207 }
208 for (int i = 0; i < _args.length; i++) {
209 args[i + 1] = _args[i];
210 }
211 final Locale local = Context.getThreadContext().getLocale();
212 final Formatter formatter = new Formatter(local);
213 formatter.format(this.format, args);
214 final String ret = formatter.toString();
215 formatter.close();
216 return ret;
217 }
218
219
220
221
222
223
224
225
226 public Long getNextValAsLong()
227 throws EFapsException
228 {
229 long ret = 0;
230 try {
231 ret = Context.getDbType().nextSequence(Context.getThreadContext().getConnection(), getDBName());
232 } catch (final SQLException e) {
233 throw new EFapsException(NumberGenerator.class, " getNextValAsLong()", e);
234 }
235 return ret;
236 }
237
238
239
240
241
242
243
244
245
246 public void setVal(final String _value)
247 throws EFapsException
248 {
249 try {
250 Context.getDbType().setSequence(Context.getThreadContext().getConnection(), getDBName(),
251 Long.valueOf(_value));
252 } catch (final SQLException e) {
253 throw new EFapsException(NumberGenerator.class, "setVal()", e);
254 }
255 }
256
257
258
259
260 @Override
261 public long getId()
262 {
263 return this.id;
264 }
265
266
267
268
269 @Override
270 public String getName()
271 {
272 return this.name;
273 }
274
275
276
277
278 @Override
279 public UUID getUUID()
280 {
281 return this.uuid;
282 }
283
284
285
286
287
288
289 public static void initialize()
290 throws CacheReloadException
291 {
292 NumberGenerator.initialize(NumberGenerator.class);
293 }
294
295
296
297
298
299
300
301 public static void initialize(final Class<?> _class)
302 throws CacheReloadException
303 {
304 if (InfinispanCache.get().exists(NumberGenerator.UUIDCACHE)) {
305 InfinispanCache.get().<UUID, NumberGenerator>getCache(NumberGenerator.UUIDCACHE).clear();
306 } else {
307 InfinispanCache.get().<UUID, NumberGenerator>getCache(NumberGenerator.UUIDCACHE)
308 .addListener(new CacheLogListener(NumberGenerator.LOG));
309 }
310 if (InfinispanCache.get().exists(NumberGenerator.IDCACHE)) {
311 InfinispanCache.get().<Long, NumberGenerator>getCache(NumberGenerator.IDCACHE).clear();
312 } else {
313 InfinispanCache.get().<Long, NumberGenerator>getCache(NumberGenerator.IDCACHE)
314 .addListener(new CacheLogListener(NumberGenerator.LOG));
315 }
316 if (InfinispanCache.get().exists(NumberGenerator.NAMECACHE)) {
317 InfinispanCache.get().<String, NumberGenerator>getCache(NumberGenerator.NAMECACHE).clear();
318 } else {
319 InfinispanCache.get().<String, NumberGenerator>getCache(NumberGenerator.NAMECACHE)
320 .addListener(new CacheLogListener(NumberGenerator.LOG));
321 }
322 }
323
324
325
326
327
328
329
330
331 public static NumberGenerator get(final long _id)
332 throws CacheReloadException
333 {
334 final Cache<Long, NumberGenerator> cache = InfinispanCache.get().<Long, NumberGenerator>getCache(
335 NumberGenerator.IDCACHE);
336 if (!cache.containsKey(_id)) {
337 NumberGenerator.getNumberGeneratorFromDB(NumberGenerator.SQL_ID, _id);
338 }
339 return cache.get(_id);
340 }
341
342
343
344
345
346
347
348
349
350 public static NumberGenerator get(final String _name)
351 throws CacheReloadException
352 {
353 final Cache<Long, NumberGenerator> cache = InfinispanCache.get().<Long, NumberGenerator>getCache(
354 NumberGenerator.NAMECACHE);
355 if (!cache.containsKey(_name)) {
356 NumberGenerator.getNumberGeneratorFromDB(NumberGenerator.SQL_NAME, _name);
357 }
358 return cache.get(_name);
359 }
360
361
362
363
364
365
366
367
368
369 public static NumberGenerator get(final UUID _uuid)
370 throws CacheReloadException
371 {
372 final Cache<UUID, NumberGenerator> cache = InfinispanCache.get().<UUID, NumberGenerator>getCache(
373 NumberGenerator.UUIDCACHE);
374 if (!cache.containsKey(_uuid)) {
375 NumberGenerator.getNumberGeneratorFromDB(NumberGenerator.SQL_UUID, String.valueOf(_uuid));
376 }
377 return cache.get(_uuid);
378 }
379
380
381
382
383 private static void cacheNumberGenerator(final NumberGenerator _numberGenerator)
384 {
385 final Cache<UUID, NumberGenerator> cache4UUID = InfinispanCache.get().<UUID, NumberGenerator>getIgnReCache(
386 NumberGenerator.UUIDCACHE);
387 cache4UUID.putIfAbsent(_numberGenerator.getUUID(), _numberGenerator);
388
389 final Cache<String, NumberGenerator> nameCache = InfinispanCache.get().<String, NumberGenerator>getIgnReCache(
390 NumberGenerator.NAMECACHE);
391 nameCache.putIfAbsent(_numberGenerator.getName(), _numberGenerator);
392
393 final Cache<Long, NumberGenerator> idCache = InfinispanCache.get().<Long, NumberGenerator>getIgnReCache(
394 NumberGenerator.IDCACHE);
395 idCache.putIfAbsent(_numberGenerator.getId(), _numberGenerator);
396 }
397
398
399
400
401
402
403
404 private static boolean getNumberGeneratorFromDB(final String _sql,
405 final Object _criteria)
406 throws CacheReloadException
407 {
408 boolean ret = false;
409 ConnectionResource con = null;
410 try {
411 con = Context.getThreadContext().getConnectionResource();
412 PreparedStatement stmt = null;
413 try {
414 stmt = con.getConnection().prepareStatement(_sql);
415 stmt.setObject(1, _criteria);
416 final ResultSet rs = stmt.executeQuery();
417 if (rs.next()) {
418 final long id = rs.getLong(1);
419 final String name = rs.getString(2).trim();
420 final String uuid = rs.getString(3).trim();
421 final String format = rs.getString(4).trim();
422 NumberGenerator.LOG.debug("read NumberGenerator '{}' (id = {}), format = '{}'", name, id, format);
423 final NumberGenerator generator = new NumberGenerator(id, name, uuid, format);
424 NumberGenerator.cacheNumberGenerator(generator);
425 }
426 ret = true;
427 rs.close();
428 } finally {
429 if (stmt != null) {
430 stmt.close();
431 }
432 }
433 con.commit();
434
435 } catch (final SQLException e) {
436 throw new CacheReloadException("could not read roles", e);
437 } catch (final EFapsException e) {
438 throw new CacheReloadException("could not read roles", e);
439 } finally {
440 if ((con != null) && con.isOpened()) {
441 try {
442 con.abort();
443 } catch (final EFapsException e) {
444 throw new CacheReloadException("could not read roles", e);
445 }
446 }
447 }
448 return ret;
449 }
450
451 @Override
452 public boolean equals(final Object _obj)
453 {
454 boolean ret;
455 if (_obj instanceof NumberGenerator) {
456 ret = ((NumberGenerator) _obj).getId() == getId();
457 } else {
458 ret = super.equals(_obj);
459 }
460 return ret;
461 }
462
463 @Override
464 public int hashCode()
465 {
466 return Long.valueOf(getId()).intValue();
467 }
468 }