Joaquín Reñé
2025-10-07 146a0fb8b0e90f9196e569152f649baf60d6cc8f
securis/src/main/java/net/curisit/securis/db/License.java
....@@ -1,3 +1,6 @@
1
+/*
2
+* Copyright @ 2013 CurisTEC, S.A.S. All Rights Reserved.
3
+*/
14 package net.curisit.securis.db;
25
36 import java.io.Serializable;
....@@ -41,438 +44,677 @@
4144 import net.curisit.securis.services.exception.SeCurisServiceException;
4245
4346 /**
44
- * Entity implementation class for Entity: license
45
- *
46
- */
47
+* License
48
+* <p>
49
+* Main license entity. Contains identity, ownership, timestamps and payload fields.
50
+* Includes convenience JSON properties for related IDs/names.
51
+*
52
+* Mapping details:
53
+* - Table: license
54
+* - Listeners: CreationTimestampListener, ModificationTimestampListener
55
+* - Named queries: license-by-code, license-by-activation-code, last-code-suffix-used-in-pack, ...
56
+* - Status column uses custom Hibernate type: net.curisit.securis.db.common.LicenseStatusType
57
+*
58
+* @author JRA
59
+* Last reviewed by JRA on Oct 5, 2025.
60
+*/
4761 @JsonAutoDetect
4862 @JsonInclude(Include.NON_NULL)
4963 @Entity
5064 @EntityListeners({ CreationTimestampListener.class, ModificationTimestampListener.class })
5165 @Table(name = "license")
5266 @JsonIgnoreProperties(ignoreUnknown = true)
53
-@NamedQueries({ @NamedQuery(name = "license-by-code", query = "SELECT l FROM License l where l.code = :code"),
54
- @NamedQuery(name = "license-by-activation-code", query = "SELECT l FROM License l where l.activationCode = :activationCode"),
55
- @NamedQuery(name = "last-code-suffix-used-in-pack", query = "SELECT max(l.codeSuffix) FROM License l where l.pack.id = :packId"),
56
- @NamedQuery(name = "list-licenses-by-pack", query = "SELECT l FROM License l where l.pack.id = :packId"),
57
- @NamedQuery(name = "list-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash"),
58
- @NamedQuery(name = "list-active-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('AC', 'PA')"),
59
- @NamedQuery(name = "list-valid-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('RE', 'AC', 'PA')")
60
-
67
+@NamedQueries({
68
+ @NamedQuery(name = "license-by-code", query = "SELECT l FROM License l where l.code = :code"),
69
+ @NamedQuery(name = "license-by-activation-code", query = "SELECT l FROM License l where l.activationCode = :activationCode"),
70
+ @NamedQuery(name = "last-code-suffix-used-in-pack", query = "SELECT max(l.codeSuffix) FROM License l where l.pack.id = :packId"),
71
+ @NamedQuery(name = "list-licenses-by-pack", query = "SELECT l FROM License l where l.pack.id = :packId"),
72
+ @NamedQuery(name = "list-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash"),
73
+ @NamedQuery(name = "list-active-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('AC', 'PA')"),
74
+ @NamedQuery(name = "list-valid-licenses-by-req-data", query = "SELECT l FROM License l where l.reqDataHash = :hash and l.status in ('RE', 'AC', 'PA')")
6175 })
6276 public class License implements CreationTimestampEntity, ModificationTimestampEntity, Serializable {
6377
64
- private static final long serialVersionUID = 2700310404904877227L;
78
+ private static final long serialVersionUID = 2700310404904877227L;
6579
66
- private static final Logger LOG = LogManager.getLogger(License.class);
80
+ private static final Logger LOG = LogManager.getLogger(License.class);
6781
68
- @Id
69
- @GeneratedValue
70
- private Integer id;
82
+ // ------------------------------------------------------------------
83
+ // Columns & relations
84
+ // ------------------------------------------------------------------
7185
72
- private String code;
86
+ @Id
87
+ @GeneratedValue
88
+ private Integer id;
7389
74
- @Column(name = "metadata_obsolete")
75
- @JsonProperty("metadata_obsolete")
76
- private Boolean metadataObsolete;
90
+ private String code;
7791
78
- @Column(name = "activation_code")
79
- @JsonProperty("activation_code")
80
- private String activationCode;
92
+ @Column(name = "metadata_obsolete")
93
+ @JsonProperty("metadata_obsolete")
94
+ private Boolean metadataObsolete;
8195
82
- @Column(name = "code_suffix")
83
- @JsonProperty("code_suffix")
84
- private Integer codeSuffix;
96
+ @Column(name = "activation_code")
97
+ @JsonProperty("activation_code")
98
+ private String activationCode;
8599
86
- @JsonIgnore
87
- @ManyToOne
88
- @JoinColumn(name = "pack_id")
89
- private Pack pack;
100
+ @Column(name = "code_suffix")
101
+ @JsonProperty("code_suffix")
102
+ private Integer codeSuffix;
90103
91
- @JsonIgnore
92
- @ManyToOne
93
- @JoinColumn(name = "created_by")
94
- private User createdBy;
104
+ @JsonIgnore
105
+ @ManyToOne
106
+ @JoinColumn(name = "pack_id")
107
+ private Pack pack;
95108
96
- @JsonIgnore
97
- @ManyToOne
98
- @JoinColumn(name = "cancelled_by")
99
- private User cancelledBy;
109
+ @JsonIgnore
110
+ @ManyToOne
111
+ @JoinColumn(name = "created_by")
112
+ private User createdBy;
100113
101
- @Type(type = "net.curisit.securis.db.common.LicenseStatusType")
102
- private LicenseStatus status;
114
+ @JsonIgnore
115
+ @ManyToOne
116
+ @JoinColumn(name = "cancelled_by")
117
+ private User cancelledBy;
103118
104
- @Column(name = "full_name")
105
- @JsonProperty("full_name")
106
- private String fullName;
119
+ @Type(type = "net.curisit.securis.db.common.LicenseStatusType")
120
+ private LicenseStatus status;
107121
108
- private String email;
122
+ @Column(name = "full_name")
123
+ @JsonProperty("full_name")
124
+ private String fullName;
109125
110
- @Column(name = "request_data")
111
- @JsonProperty("request_data")
112
- private String requestData;
126
+ private String email;
113127
114
- /**
115
- * request data hash is automatically set when we use
116
- * {@link License#setRequestData(String)} method
117
- */
118
- @Column(name = "request_data_hash")
119
- @JsonIgnore
120
- private String reqDataHash;
128
+ @Column(name = "request_data")
129
+ @JsonProperty("request_data")
130
+ private String requestData;
121131
122
- @Column(name = "license_data")
123
- @JsonProperty("license_data")
124
- @JsonIgnore
125
- // The license data is sent to user as a separate file, It doesn't need to
126
- // be included as License attribute on browser
127
- private String licenseData;
132
+ /**
133
+ * Request data hash (not serialized). Automatically updated by setRequestData().
134
+ */
135
+ @Column(name = "request_data_hash")
136
+ @JsonIgnore
137
+ private String reqDataHash;
128138
129
- @Column(name = "creation_timestamp")
130
- @JsonProperty("creation_timestamp")
131
- private Date creationTimestamp;
139
+ @Column(name = "license_data")
140
+ @JsonProperty("license_data")
141
+ @JsonIgnore
142
+ // License data is delivered separately (e.g., file download). Not sent in list views.
143
+ private String licenseData;
132144
133
- @Column(name = "modification_timestamp")
134
- @JsonProperty("modification_timestamp")
135
- private Date modificationTimestamp;
145
+ @Column(name = "creation_timestamp")
146
+ @JsonProperty("creation_timestamp")
147
+ private Date creationTimestamp;
136148
137
- @Column(name = "last_access_timestamp")
138
- @JsonProperty("last_access_timestamp")
139
- private Date lastAccessTimestamp;
149
+ @Column(name = "modification_timestamp")
150
+ @JsonProperty("modification_timestamp")
151
+ private Date modificationTimestamp;
140152
141
- @Column(name = "expiration_date")
142
- @JsonProperty("expiration_date")
143
- private Date expirationDate;
153
+ @Column(name = "last_access_timestamp")
154
+ @JsonProperty("last_access_timestamp")
155
+ private Date lastAccessTimestamp;
144156
145
- private String comments;
157
+ @Column(name = "expiration_date")
158
+ @JsonProperty("expiration_date")
159
+ private Date expirationDate;
146160
147
- @OneToMany(fetch = FetchType.LAZY, mappedBy = "license")
148
- @JsonIgnore
149
- private List<LicenseHistory> history;
161
+ private String comments;
150162
151
- public Integer getId() {
152
- return id;
153
- }
163
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "license")
164
+ @JsonIgnore
165
+ private List<LicenseHistory> history;
154166
155
- public String getCode() {
156
- return code;
157
- }
167
+ // ------------------------------------------------------------------
168
+ // Basic accessors
169
+ // ------------------------------------------------------------------
158170
159
- public void setCode(String code) {
160
- this.code = code;
161
- }
171
+ /**
172
+ * getId<p>
173
+ * Return primary key.
174
+ *
175
+ * @return id
176
+ */
177
+ public Integer getId() { return id; }
162178
163
- @Override
164
- public Date getCreationTimestamp() {
165
- return creationTimestamp;
166
- }
179
+ /**
180
+ * getCode<p>
181
+ * Return human-readable license code.
182
+ *
183
+ * @return code
184
+ */
185
+ public String getCode() { return code; }
167186
168
- @Override
169
- public void setCreationTimestamp(Date creationTimestamp) {
170
- this.creationTimestamp = creationTimestamp;
171
- }
187
+ /**
188
+ * setCode<p>
189
+ * Set human-readable license code.
190
+ *
191
+ * @param code
192
+ */
193
+ public void setCode(String code) { this.code = code; }
172194
173
- public User getCreatedBy() {
174
- return createdBy;
175
- }
195
+ /**
196
+ * getCreationTimestamp<p>
197
+ * Required by CreationTimestampEntity.
198
+ *
199
+ * @return creationTimestamp
200
+ */
201
+ @Override
202
+ public Date getCreationTimestamp() { return creationTimestamp; }
176203
177
- public void setCreatedBy(User createdBy) {
178
- this.createdBy = createdBy;
179
- }
204
+ /**
205
+ * setCreationTimestamp<p>
206
+ * Set creation timestamp.
207
+ *
208
+ * @param creationTimestamp
209
+ */
210
+ @Override
211
+ public void setCreationTimestamp(Date creationTimestamp) { this.creationTimestamp = creationTimestamp; }
180212
181
- public Pack getPack() {
182
- return pack;
183
- }
213
+ /**
214
+ * getCreatedBy<p>
215
+ * Return creator user (entity).
216
+ *
217
+ * @return user
218
+ */
219
+ public User getCreatedBy() { return createdBy; }
184220
185
- public void setPack(Pack pack) {
186
- this.pack = pack;
187
- }
221
+ /**
222
+ * setCreatedBy<p>
223
+ * Set creator user (entity).
224
+ *
225
+ * @param user
226
+ */
227
+ public void setCreatedBy(User createdBy) { this.createdBy = createdBy; }
188228
189
- @JsonProperty("created_by_id")
190
- public String getCreatedById() {
191
- return createdBy == null ? null : createdBy.getUsername();
192
- }
229
+ /**
230
+ * getPack<p>
231
+ * Return owning pack.
232
+ *
233
+ * @return pack
234
+ */
235
+ public Pack getPack() { return pack; }
193236
194
- @JsonProperty("created_by_id")
195
- public void setCreatedById(String username) {
196
- if (username == null) {
197
- createdBy = null;
198
- } else {
199
- createdBy = new User();
200
- createdBy.setUsername(username);
201
- }
202
- }
237
+ /**
238
+ * setPack<p>
239
+ * Set owning pack.
240
+ *
241
+ * @param pack
242
+ */
243
+ public void setPack(Pack pack) { this.pack = pack; }
203244
204
- @JsonProperty("cancelled_by_id")
205
- public String getCancelledById() {
206
- return cancelledBy == null ? null : cancelledBy.getUsername();
207
- }
245
+ /**
246
+ * getCreatedById<p>
247
+ * Expose creator username as JSON.
248
+ *
249
+ * @return username
250
+ */
251
+ @JsonProperty("created_by_id")
252
+ public String getCreatedById() { return createdBy == null ? null : createdBy.getUsername(); }
208253
209
- @JsonProperty("cancelled_by_id")
210
- public void setCancelledById(String username) {
211
- if (username == null) {
212
- cancelledBy = null;
213
- } else {
214
- cancelledBy = new User();
215
- cancelledBy.setUsername(username);
216
- }
217
- }
254
+ /**
255
+ * setCreatedById<p>
256
+ * Setter by username for JSON binding.
257
+ *
258
+ * @param username
259
+ */
260
+ @JsonProperty("created_by_id")
261
+ public void setCreatedById(String username) {
262
+ if (username == null) {
263
+ createdBy = null;
264
+ } else {
265
+ createdBy = new User();
266
+ createdBy.setUsername(username);
267
+ }
268
+ }
218269
219
- @JsonProperty("pack_code")
220
- public String getPackCode() {
221
- return pack == null ? null : pack.getCode();
222
- }
270
+ /**
271
+ * getCancelledById<p>
272
+ * Expose cancelling user username as JSON.
273
+ *
274
+ * @return username
275
+ */
276
+ @JsonProperty("cancelled_by_id")
277
+ public String getCancelledById() { return cancelledBy == null ? null : cancelledBy.getUsername(); }
223278
224
- @JsonProperty("pack_id")
225
- public Integer getPackId() {
226
- return pack == null ? null : pack.getId();
227
- }
279
+ /**
280
+ * setCancelledById<p>
281
+ * Setter by username for JSON binding.
282
+ *
283
+ * @param username
284
+ */
285
+ @JsonProperty("cancelled_by_id")
286
+ public void setCancelledById(String username) {
287
+ if (username == null) {
288
+ cancelledBy = null;
289
+ } else {
290
+ cancelledBy = new User();
291
+ cancelledBy.setUsername(username);
292
+ }
293
+ }
228294
229
- @JsonProperty("pack_id")
230
- public void setPackId(Integer idPack) {
231
- if (idPack == null) {
232
- pack = null;
233
- } else {
234
- pack = new Pack();
235
- pack.setId(idPack);
236
- }
237
- }
295
+ /**
296
+ * getPackCode<p>
297
+ * Expose pack code for convenience.
298
+ *
299
+ * @return packCode
300
+ */
301
+ @JsonProperty("pack_code")
302
+ public String getPackCode() { return pack == null ? null : pack.getCode(); }
238303
239
- public LicenseStatus getStatus() {
240
- return status;
241
- }
304
+ /**
305
+ * getPackId<p>
306
+ * Expose pack id for convenience.
307
+ *
308
+ * @return packId
309
+ */
310
+ @JsonProperty("pack_id")
311
+ public Integer getPackId() { return pack == null ? null : pack.getId(); }
242312
243
- public void setStatus(LicenseStatus status) {
244
- this.status = status;
245
- }
313
+ /**
314
+ * setPackId<p>
315
+ * Setter by id for JSON binding (creates a shallow Pack).
316
+ *
317
+ * @param packId
318
+ */
319
+ @JsonProperty("pack_id")
320
+ public void setPackId(Integer idPack) {
321
+ if (idPack == null) {
322
+ pack = null;
323
+ } else {
324
+ pack = new Pack();
325
+ pack.setId(idPack);
326
+ }
327
+ }
246328
247
- @Override
248
- public Date getModificationTimestamp() {
249
- return modificationTimestamp;
250
- }
329
+ /**
330
+ * getStatus<p>
331
+ * Return license status.
332
+ *
333
+ * @return licenseStatus
334
+ */
335
+ public LicenseStatus getStatus() { return status; }
251336
252
- @Override
253
- public void setModificationTimestamp(Date modificationTimestamp) {
254
- this.modificationTimestamp = modificationTimestamp;
255
- }
337
+ /**
338
+ * setStatus<p>
339
+ * Set license status.
340
+ *
341
+ * @param status
342
+ */
343
+ public void setStatus(LicenseStatus status) { this.status = status; }
256344
257
- public String getFullName() {
258
- return fullName;
259
- }
345
+ /**
346
+ * getModificationTimestamp<p>
347
+ * Required by ModificationTimestampEntity.
348
+ *
349
+ * @return modificationTimestamp
350
+ */
351
+ @Override
352
+ public Date getModificationTimestamp() { return modificationTimestamp; }
260353
261
- public void setFullName(String fullName) {
262
- this.fullName = fullName;
263
- }
354
+ /**
355
+ * setModificationTimestamp<p>
356
+ * Set modification timestamp.
357
+ *
358
+ * @param modificationTimestamp
359
+ */
360
+ @Override
361
+ public void setModificationTimestamp(Date modificationTimestamp) { this.modificationTimestamp = modificationTimestamp; }
264362
265
- public String getEmail() {
266
- return email;
267
- }
363
+ /**
364
+ * getFullName<p>
365
+ * Return license holder full name.
366
+ *
367
+ * @return name
368
+ */
369
+ public String getFullName() { return fullName; }
268370
269
- public void setEmail(String email) {
270
- this.email = email;
271
- }
371
+ /**
372
+ * setFullName<p>
373
+ * Set license holder full name.
374
+ *
375
+ * @param name
376
+ */
377
+ public void setFullName(String fullName) { this.fullName = fullName; }
272378
273
- public void setId(Integer id) {
274
- this.id = id;
275
- }
379
+ /**
380
+ * getEmail<p>
381
+ * Return email address.
382
+ *
383
+ * @return email
384
+ */
385
+ public String getEmail() { return email; }
276386
277
- public User getCancelledBy() {
278
- return cancelledBy;
279
- }
387
+ /**
388
+ * setEmail<p>
389
+ * Set email address.
390
+ *
391
+ * @param email
392
+ */
393
+ public void setEmail(String email) { this.email = email; }
394
+
395
+ /**
396
+ * setId<p>
397
+ * Set primary key (rarely used).
398
+ *
399
+ * @param id
400
+ */
401
+ public void setId(Integer id) { this.id = id; }
402
+
403
+ /**
404
+ * getCancelledBy<p>
405
+ * Return cancelling user (entity).
406
+ *
407
+ * @param user
408
+ */
409
+ public User getCancelledBy() { return cancelledBy; }
410
+
411
+ /**
412
+ * setCancelledBy<p>
413
+ * Set cancelling user (entity).
414
+ *
415
+ * @param cancelledBy
416
+ */
417
+ public void setCancelledBy(User cancelledBy) { this.cancelledBy = cancelledBy; }
280418
281
- public void setCancelledBy(User cancelledBy) {
282
- this.cancelledBy = cancelledBy;
283
- }
419
+ /**
420
+ * getLastAccessTimestamp<p>
421
+ * Return last access timestamp.
422
+ *
423
+ * @return lastAccessTimestamp
424
+ */
425
+ public Date getLastAccessTimestamp() { return lastAccessTimestamp; }
284426
285
- public Date getLastAccessTimestamp() {
286
- return lastAccessTimestamp;
287
- }
427
+ /**
428
+ * setLastAccessTimestamp<p>
429
+ * Set last access timestamp.
430
+ *
431
+ * @param lastAccessTimestamp
432
+ */
433
+ public void setLastAccessTimestamp(Date lastAccessTimestamp) { this.lastAccessTimestamp = lastAccessTimestamp; }
288434
289
- public void setLastAccessTimestamp(Date lastAccessTimestamp) {
290
- this.lastAccessTimestamp = lastAccessTimestamp;
291
- }
435
+ /**
436
+ * getRequestData<p>
437
+ * Return raw request data.
438
+ *
439
+ * @return requestData
440
+ */
441
+ public String getRequestData() { return requestData; }
292442
293
- public String getRequestData() {
294
- return requestData;
295
- }
443
+ /**
444
+ * setRequestData<p>
445
+ * Set raw request data and recompute {@link #reqDataHash} immediately using
446
+ * the same hashing strategy as BlockedRequest (SHA-256).
447
+ *
448
+ * @param requestData
449
+ */
450
+ public void setRequestData(String requestData) {
451
+ this.requestData = requestData;
452
+ this.reqDataHash = BlockedRequest.generateHash(this.requestData);
453
+ }
296454
297
- public void setRequestData(String requestData) {
298
- this.requestData = requestData;
299
- this.reqDataHash = BlockedRequest.generateHash(this.requestData);
300
- }
455
+ /**
456
+ * getLicenseData<p>
457
+ * Return opaque license data (not serialized in lists).
458
+ *
459
+ * @return licenseData
460
+ */
461
+ public String getLicenseData() { return licenseData; }
301462
302
- public String getLicenseData() {
303
- return licenseData;
304
- }
463
+ /**
464
+ * setLicenseData<p>
465
+ * Set opaque license data (large content kept server-side).
466
+ *
467
+ * @param licenseDate
468
+ */
469
+ public void setLicenseData(String licenseData) { this.licenseData = licenseData; }
305470
306
- public void setLicenseData(String licenseData) {
307
- this.licenseData = licenseData;
308
- }
471
+ /**
472
+ * getComments<p>
473
+ * Return optional comments.
474
+ *
475
+ * @return comments
476
+ */
477
+ public String getComments() { return comments; }
309478
310
- public String getComments() {
311
- return comments;
312
- }
479
+ /**
480
+ * setComments<p>
481
+ * Set optional comments.
482
+ *
483
+ * @param comments
484
+ */
485
+ public void setComments(String comments) { this.comments = comments; }
313486
314
- public void setComments(String comments) {
315
- this.comments = comments;
316
- }
487
+ /**
488
+ * getHistory<p>
489
+ * Return change history entries (lazy).
490
+ *
491
+ * @return history
492
+ */
493
+ public List<LicenseHistory> getHistory() { return history; }
317494
318
- public List<LicenseHistory> getHistory() {
319
- return history;
320
- }
495
+ /**
496
+ * setHistory<p>
497
+ * Set change history entries.
498
+ *
499
+ * @param history
500
+ */
501
+ public void setHistory(List<LicenseHistory> history) { this.history = history; }
321502
322
- public void setHistory(List<LicenseHistory> history) {
323
- this.history = history;
324
- }
503
+ /**
504
+ * getExpirationDate<p>
505
+ * Return expiration date (nullable).
506
+ *
507
+ * @return expirationDate
508
+ */
509
+ public Date getExpirationDate() { return expirationDate; }
325510
326
- public Date getExpirationDate() {
327
- return expirationDate;
328
- }
511
+ /**
512
+ * setExpirationDate<p>
513
+ * Set expiration date (nullable).
514
+ *
515
+ * @param expirationDate
516
+ */
517
+ public void setExpirationDate(Date expirationDate) { this.expirationDate = expirationDate; }
329518
330
- public void setExpirationDate(Date expirationDate) {
331
- this.expirationDate = expirationDate;
332
- }
519
+ /**
520
+ * getReqDataHash<p>
521
+ * Return cached hash of request data (not exposed in JSON).
522
+ *
523
+ * @return reqDataHash
524
+ */
525
+ public String getReqDataHash() { return reqDataHash; }
333526
334
- public String getReqDataHash() {
335
- return reqDataHash;
336
- }
527
+ /**
528
+ * getCodeSuffix<p>
529
+ * Return numeric suffix of the code.
530
+ *
531
+ * @return codeSuffix
532
+ */
533
+ public Integer getCodeSuffix() { return codeSuffix; }
337534
338
- public static class Action {
339
- public static final int CREATE = 1;
340
- public static final int REQUEST = 2;
341
- public static final int ACTIVATION = 3;
342
- public static final int SEND = 4;
343
- public static final int DOWNLOAD = 5;
344
- public static final int CANCEL = 6;
345
- public static final int DELETE = 7;
346
- public static final int BLOCK = 8;
347
- public static final int UNBLOCK = 9;
348
- }
535
+ /**
536
+ * setCodeSuffix<p>
537
+ * Set numeric suffix of the code.
538
+ *
539
+ * @param codeSuffix
540
+ */
541
+ public void setCodeSuffix(Integer codeSuffix) { this.codeSuffix = codeSuffix; }
349542
350
- public static class Status {
543
+ /**
544
+ * getActivationCode<p>
545
+ * Return activation code.
546
+ *
547
+ * @return activationCode
548
+ */
549
+ public String getActivationCode() { return activationCode; }
351550
352
- private static final Map<Integer, List<LicenseStatus>> transitions = Utils.createMap( //
353
- Action.REQUEST, Arrays.asList(LicenseStatus.CREATED, LicenseStatus.REQUESTED), //
354
- Action.ACTIVATION, Arrays.asList(LicenseStatus.CREATED, LicenseStatus.REQUESTED, LicenseStatus.PRE_ACTIVE, LicenseStatus.EXPIRED), //
355
- Action.SEND, Arrays.asList(LicenseStatus.ACTIVE, LicenseStatus.PRE_ACTIVE), //
356
- Action.DOWNLOAD, Arrays.asList(LicenseStatus.ACTIVE, LicenseStatus.PRE_ACTIVE), //
357
- Action.CANCEL, Arrays.asList(LicenseStatus.ACTIVE, LicenseStatus.PRE_ACTIVE, LicenseStatus.REQUESTED, LicenseStatus.EXPIRED), //
358
- Action.DELETE, Arrays.asList(LicenseStatus.CANCELLED, LicenseStatus.CREATED, LicenseStatus.BLOCKED), //
359
- Action.UNBLOCK, Arrays.asList(LicenseStatus.BLOCKED), //
360
- Action.BLOCK, Arrays.asList(LicenseStatus.CANCELLED) //
361
- );
551
+ /**
552
+ * setActivationCode<p>
553
+ * Set activation code.
554
+ *
555
+ * @param activationCode
556
+ */
557
+ public void setActivationCode(String activationCode) { this.activationCode = activationCode; }
362558
363
- /**
364
- * It checks if a given action is valid for the License, passing the
365
- * action and the current license status
366
- *
367
- * @param oldStatus
368
- * @param newStatus
369
- * @return
370
- */
371
- public static boolean isActionValid(Integer action, LicenseStatus currentStatus) {
372
- List<LicenseStatus> validStatuses = transitions.get(action);
373
- LOG.info("Action {} is valid ? => {} current: {} OK? {}", action, validStatuses, currentStatus, validStatuses.contains(currentStatus));
374
- return validStatuses != null && validStatuses.contains(currentStatus);
375
- }
376
- }
559
+ /**
560
+ * isMetadataObsolete<p>
561
+ * Convenience Boolean → primitive with null-safe false.
562
+ *
563
+ * @return isMetadataObsolete
564
+ */
565
+ public boolean isMetadataObsolete() { return metadataObsolete != null && metadataObsolete; }
377566
378
- /**
379
- * Return licenses with status: REquested, ACtive, Pre-Active for a given
380
- * request data
381
- *
382
- * @param requestData
383
- * @param em
384
- * @return
385
- * @throws SeCurisServiceException
386
- */
387
- public static License findValidLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
388
- TypedQuery<License> query = em.createNamedQuery("list-valid-licenses-by-req-data", License.class);
389
- query.setParameter("hash", BlockedRequest.generateHash(requestData));
390
- try {
391
- List<License> list = query.getResultList();
392
- if (list.size() == 0) {
393
- return null;
394
- }
395
- if (list.size() > 1) {
396
- LOG.error("There are more than 1 active or requested license for request data: {}\nHash: {}", requestData, BlockedRequest.generateHash(requestData));
397
- }
398
- return list.get(0);
399
- } catch (NoResultException e) {
400
- // There is no license for request data
401
- return null;
402
- }
403
- }
567
+ /**
568
+ * setMetadataObsolete<p>
569
+ * Set metadata obsolete flag (nullable wrapper).
570
+ *
571
+ * @param obsolete
572
+ */
573
+ public void setMetadataObsolete(Boolean obsolete) { this.metadataObsolete = obsolete; }
404574
405
- /**
406
- * Return licenses with status: REquested, ACtive, Pre-Active for a given
407
- * request data
408
- *
409
- * @param requestData
410
- * @param em
411
- * @return
412
- * @throws SeCurisServiceException
413
- */
414
- public static License findLicenseByActivationCode(String activationCode, EntityManager em) throws SeCurisServiceException {
415
- TypedQuery<License> query = em.createNamedQuery("license-by-activation-code", License.class);
416
- query.setParameter("activationCode", activationCode);
417
- try {
418
- return query.getSingleResult();
419
- } catch (NoResultException e) {
420
- // There is no license for request data
421
- return null;
422
- }
423
- }
575
+ // ------------------------------------------------------------------
576
+ // Status transitions helpers
577
+ // ------------------------------------------------------------------
424578
425
- public static License findActiveLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
426
- TypedQuery<License> query = em.createNamedQuery("list-active-licenses-by-req-data", License.class);
427
- query.setParameter("hash", BlockedRequest.generateHash(requestData));
428
- try {
429
- List<License> list = query.getResultList();
430
- if (list.size() == 0) {
431
- return null;
432
- }
433
- if (list.size() > 1) {
434
- LOG.error("There are more than 1 active license for request data: {}\nHash: {}", requestData, BlockedRequest.generateHash(requestData));
435
- }
436
- return list.get(0);
437
- } catch (NoResultException e) {
438
- // There is no license for request data
439
- return null;
440
- }
441
- }
579
+ /**
580
+ * Action<p>
581
+ * Actions to take with the license
582
+ */
583
+ public static class Action {
584
+ public static final int CREATE = 1;
585
+ public static final int REQUEST = 2;
586
+ public static final int ACTIVATION = 3;
587
+ public static final int SEND = 4;
588
+ public static final int DOWNLOAD = 5;
589
+ public static final int CANCEL = 6;
590
+ public static final int DELETE = 7;
591
+ public static final int BLOCK = 8;
592
+ public static final int UNBLOCK = 9;
593
+ }
442594
443
- public static License findLicenseByCode(String code, EntityManager em) throws SeCurisServiceException {
444
- TypedQuery<License> query = em.createNamedQuery("license-by-code", License.class);
445
- query.setParameter("code", code);
446
- try {
447
- return query.getSingleResult();
448
- } catch (NoResultException e) {
449
- // There is no license for request data
450
- return null;
451
- }
452
- }
595
+ /**
596
+ * Status<p>
597
+ * Status of the requested license
598
+ */
599
+ public static class Status {
453600
454
- public Integer getCodeSuffix() {
455
- return codeSuffix;
456
- }
601
+ private static final Map<Integer, List<LicenseStatus>> transitions = Utils.createMap(
602
+ Action.REQUEST, Arrays.asList(LicenseStatus.CREATED, LicenseStatus.REQUESTED),
603
+ Action.ACTIVATION,Arrays.asList(LicenseStatus.CREATED, LicenseStatus.REQUESTED, LicenseStatus.PRE_ACTIVE, LicenseStatus.EXPIRED),
604
+ Action.SEND, Arrays.asList(LicenseStatus.ACTIVE, LicenseStatus.PRE_ACTIVE),
605
+ Action.DOWNLOAD, Arrays.asList(LicenseStatus.ACTIVE, LicenseStatus.PRE_ACTIVE),
606
+ Action.CANCEL, Arrays.asList(LicenseStatus.ACTIVE, LicenseStatus.PRE_ACTIVE, LicenseStatus.REQUESTED, LicenseStatus.EXPIRED),
607
+ Action.DELETE, Arrays.asList(LicenseStatus.CANCELLED, LicenseStatus.CREATED, LicenseStatus.BLOCKED),
608
+ Action.UNBLOCK, Arrays.asList(LicenseStatus.BLOCKED),
609
+ Action.BLOCK, Arrays.asList(LicenseStatus.CANCELLED)
610
+ );
457611
458
- public void setCodeSuffix(Integer codeSuffix) {
459
- this.codeSuffix = codeSuffix;
460
- }
612
+ /**
613
+ * isActionValid<p>
614
+ * Check whether an action is valid given the current license status.
615
+ *
616
+ * @param action action constant from {@link Action}
617
+ * @param currentStatus current license status
618
+ * @return true if allowed
619
+ */
620
+ public static boolean isActionValid(Integer action, LicenseStatus currentStatus) {
621
+ List<LicenseStatus> validStatuses = transitions.get(action);
622
+ LOG.info("Action {} is valid ? => {} current: {} OK? {}", action, validStatuses, currentStatus,
623
+ validStatuses != null && validStatuses.contains(currentStatus));
624
+ return validStatuses != null && validStatuses.contains(currentStatus);
625
+ }
626
+ }
461627
462
- public String getActivationCode() {
463
- return activationCode;
464
- }
628
+ // ------------------------------------------------------------------
629
+ // Repository helpers (static queries)
630
+ // ------------------------------------------------------------------
465631
466
- public void setActivationCode(String activationCode) {
467
- this.activationCode = activationCode;
468
- }
632
+ /**
633
+ * findValidLicenseByRequestData<p>
634
+ * Return the first license in statuses RE/AC/PA for the given request data hash.
635
+ *
636
+ * @param requestData raw request data
637
+ * @param em entity manager
638
+ * @return matching license or null
639
+ * @throws SeCurisServiceException
640
+ */
641
+ public static License findValidLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
642
+ TypedQuery<License> query = em.createNamedQuery("list-valid-licenses-by-req-data", License.class);
643
+ query.setParameter("hash", BlockedRequest.generateHash(requestData));
644
+ try {
645
+ List<License> list = query.getResultList();
646
+ if (list.size() == 0) return null;
647
+ if (list.size() > 1) {
648
+ LOG.error("There are more than 1 active or requested license for request data: {}\nHash: {}",
649
+ requestData, BlockedRequest.generateHash(requestData));
650
+ }
651
+ return list.get(0);
652
+ } catch (NoResultException e) {
653
+ return null;
654
+ }
655
+ }
469656
470
- public boolean isMetadataObsolete() {
471
- return metadataObsolete != null && metadataObsolete;
472
- }
657
+ /**
658
+ * findLicenseByActivationCode<p>
659
+ * Retrieve a license by its activation code.
660
+ *
661
+ * @param activationCode
662
+ * @param entityManager
663
+ * @return license
664
+ * @throws SeCurisServiceException
665
+ */
666
+ public static License findLicenseByActivationCode(String activationCode, EntityManager em) throws SeCurisServiceException {
667
+ TypedQuery<License> query = em.createNamedQuery("license-by-activation-code", License.class);
668
+ query.setParameter("activationCode", activationCode);
669
+ try {
670
+ return query.getSingleResult();
671
+ } catch (NoResultException e) {
672
+ return null;
673
+ }
674
+ }
473675
474
- public void setMetadataObsolete(Boolean obsolete) {
475
- this.metadataObsolete = obsolete;
476
- }
676
+ /**
677
+ * findActiveLicenseByRequestData<p>
678
+ * Return the first AC/PA license for a given requestData.
679
+ *
680
+ * @param requestData
681
+ * @param entityManager
682
+ * @return license
683
+ * @throws SeCurisServiceException
684
+ */
685
+ public static License findActiveLicenseByRequestData(String requestData, EntityManager em) throws SeCurisServiceException {
686
+ TypedQuery<License> query = em.createNamedQuery("list-active-licenses-by-req-data", License.class);
687
+ query.setParameter("hash", BlockedRequest.generateHash(requestData));
688
+ try {
689
+ List<License> list = query.getResultList();
690
+ if (list.size() == 0) return null;
691
+ if (list.size() > 1) {
692
+ LOG.error("There are more than 1 active license for request data: {}\nHash: {}",
693
+ requestData, BlockedRequest.generateHash(requestData));
694
+ }
695
+ return list.get(0);
696
+ } catch (NoResultException e) {
697
+ return null;
698
+ }
699
+ }
477700
701
+ /**
702
+ * findLicenseByCode<p>
703
+ * Retrieve a license by human-readable code.
704
+ *
705
+ * @param code
706
+ * @param entityManager
707
+ * @return license
708
+ * @throws SeCurisServiceException
709
+ */
710
+ public static License findLicenseByCode(String code, EntityManager em) throws SeCurisServiceException {
711
+ TypedQuery<License> query = em.createNamedQuery("license-by-code", License.class);
712
+ query.setParameter("code", code);
713
+ try {
714
+ return query.getSingleResult();
715
+ } catch (NoResultException e) {
716
+ return null;
717
+ }
718
+ }
478719 }
720
+