1 package fr.ifremer.dali.decorator;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import fr.ifremer.dali.config.DaliConfiguration;
27 import fr.ifremer.dali.dto.*;
28 import fr.ifremer.dali.dto.configuration.context.ContextDTO;
29 import fr.ifremer.dali.dto.configuration.control.RuleListDTO;
30 import fr.ifremer.dali.dto.configuration.filter.FilterDTO;
31 import fr.ifremer.dali.dto.configuration.programStrategy.ProgramDTO;
32 import fr.ifremer.dali.dto.configuration.programStrategy.StrategyDTO;
33 import fr.ifremer.dali.dto.data.sampling.SamplingOperationDTO;
34 import fr.ifremer.dali.dto.data.survey.OccasionDTO;
35 import fr.ifremer.dali.dto.referential.*;
36 import fr.ifremer.dali.dto.referential.pmfm.ParameterDTO;
37 import fr.ifremer.dali.dto.referential.pmfm.PmfmDTO;
38 import fr.ifremer.dali.dto.referential.pmfm.QualitativeValueDTO;
39 import fr.ifremer.dali.dto.system.extraction.ExtractionDTO;
40 import fr.ifremer.dali.dto.system.extraction.ExtractionPeriodDTO;
41 import fr.ifremer.dali.dto.system.extraction.FilterTypeDTO;
42 import fr.ifremer.dali.dto.system.synchronization.SynchroTableDTO;
43 import fr.ifremer.quadrige3.core.dao.technical.AlphanumericComparator;
44 import fr.ifremer.quadrige3.core.dao.technical.Assert;
45 import fr.ifremer.quadrige3.core.dao.technical.Dates;
46 import fr.ifremer.quadrige3.core.dao.technical.Times;
47 import fr.ifremer.quadrige3.core.dao.technical.decorator.Decorator;
48 import fr.ifremer.quadrige3.core.vo.administration.program.ProgramVO;
49 import fr.ifremer.quadrige3.core.vo.data.survey.LightSurveyVO;
50 import fr.ifremer.quadrige3.ui.core.dto.CodeOnly;
51 import fr.ifremer.quadrige3.ui.core.dto.MonthDTO;
52 import fr.ifremer.quadrige3.ui.core.dto.referential.BaseReferentialDTO;
53 import fr.ifremer.quadrige3.ui.core.dto.referential.StatusDTO;
54 import org.apache.commons.collections4.CollectionUtils;
55 import org.apache.commons.lang3.ArrayUtils;
56 import org.apache.commons.lang3.StringUtils;
57
58 import java.io.File;
59 import java.util.concurrent.TimeUnit;
60
61 import static org.nuiton.i18n.I18n.t;
62
63
64
65
66
67
68
69 public class DecoratorServiceImpl extends fr.ifremer.quadrige3.core.service.decorator.DecoratorServiceImpl
70 implements DecoratorService {
71
72
73
74
75 @Override
76 protected void onLoadDecorators(fr.ifremer.quadrige3.core.dao.technical.decorator.DecoratorProvider provider) {
77
78
79 provider.registerDecorator(AnalysisInstrumentDTO.class, CODE, "${id}$s", TOKEN_SEPARATOR, SEPARATOR);
80 provider.registerDecorator(AnalysisInstrumentDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
81 provider.registerDecorator(DepartmentDTO.class, "${code}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
82 provider.registerDecorator(DepartmentDTO.class, CODE, "${code}$s", TOKEN_SEPARATOR, SEPARATOR);
83 provider.registerDecorator(DepartmentDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
84 provider.registerDecorator(LocationDTO.class, "${label}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
85 provider.registerDecorator(LocationDTO.class, CODE, "${label}$s", TOKEN_SEPARATOR, SEPARATOR);
86 provider.registerDecorator(LocationDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
87 provider.registerDecorator(HarbourDTO.class, "${code}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
88 provider.registerDecorator(ParameterDTO.class, "${transcribedCode}$s", TOKEN_SEPARATOR, SEPARATOR);
89 provider.registerDecorator(ParameterDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
90 provider.registerDecorator(ParameterDTO.class, CODE_NAME, "${transcribedCode}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
91 provider.registerDecorator(PersonDTO.class, "${firstName}$s#${name}$s - ${department/name}$s", TOKEN_SEPARATOR, " ");
92 provider.registerDecorator(PrivilegeDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
93 provider.registerDecorator(new PMFMDecorator());
94 provider.registerDecorator(NAME, new PMFMNameDecorator());
95 provider.registerDecorator(NAME_WITH_UNIT, new PMFMNameWithUnitDecorator());
96 provider.registerDecorator(NAME_WITH_ID, new PMFMNameWithIdDecorator());
97 provider.registerDecorator(new SortedQualitativeValueDecorator());
98 provider.registerDecorator(UnitDTO.class, WITH_SYMBOL, "${name}$s (${symbol}$s)", TOKEN_SEPARATOR, SEPARATOR);
99 provider.registerDecorator(new TaxonDecorator());
100 provider.registerDecorator(TaxonDTO.class, CODE, "${id}$s", TOKEN_SEPARATOR, SEPARATOR);
101 provider.registerDecorator(WITH_CITATION, new TaxonWithCitationDecorator());
102 provider.registerDecorator(WITH_REFERENT, new TaxonWithReferentDecorator());
103 provider.registerDecorator(WITH_CITATION_AND_REFERENT, new TaxonWithCitationAndReferentDecorator());
104 provider.registerDecorator(TaxonGroupDTO.class, "${label}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
105 provider.registerDecorator(TaxonGroupDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
106 provider.registerDecorator(SamplingEquipmentDTO.class, CODE, "${id}$s", TOKEN_SEPARATOR, SEPARATOR);
107 provider.registerDecorator(SamplingEquipmentDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
108 provider.registerDecorator(StatusDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
109 provider.registerDecorator(PositioningSystemDTO.class, CODE_NAME, "${code}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
110
111
112 provider.registerDecorator(ExtractionDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
113 provider.registerDecorator(FilterTypeDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
114 provider.registerDecorator(ExtractionPeriodDTO.class, "${startDate}$td/%1$tm/%1$tY#${endDate}$td/%2$tm/%2$tY", TOKEN_SEPARATOR, " => ");
115
116
117 provider.registerDecorator(ContextDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
118 provider.registerDecorator(FilterDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
119 provider.registerDecorator(ProgramDTO.class, "${code}$s#${name}$s", TOKEN_SEPARATOR, SEPARATOR);
120 provider.registerDecorator(ProgramDTO.class, NAME, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
121 provider.registerDecorator(ProgramDTO.class, CODE, "${code}$s", TOKEN_SEPARATOR, SEPARATOR);
122 provider.registerDecorator(StrategyDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
123
124
125 provider.registerDecorator(RuleListDTO.class, "${code}$s", TOKEN_SEPARATOR, SEPARATOR);
126
127
128 provider.registerDecorator(BaseReferentialDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
129
130 provider.registerDecorator(CodeOnly.class, "${code}$s", TOKEN_SEPARATOR, SEPARATOR);
131
132
133 provider.registerDecorator(OccasionDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
134 provider.registerDecorator(SamplingOperationDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
135 provider.registerDecorator(CONCAT, new SamplingOperationDecorator());
136 provider.registerDecorator(new LightSurveyVODecorator());
137
138
139 provider.registerDecorator(ParameterTypeDTO.class, "${keyLabel}$s", TOKEN_SEPARATOR, SEPARATOR);
140 provider.registerDecorator(StateDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
141 provider.registerDecorator(FunctionDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
142 provider.registerDecorator(SynchronizationStatusDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
143 provider.registerDecorator(SearchDateDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
144 provider.registerDecorator(MonthDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR);
145
146
147 provider.registerDecorator(new SynchroTableWithCountDecorator());
148 provider.registerDecorator(WITH_COUNT, new SynchroTableWithCountDecorator(WITH_COUNT));
149
150
151 provider.registerDecorator(COLLECTION_SIZE, new CollectionSizeDecorator());
152 provider.registerDecorator(DURATION_IN_MINUTES, new DurationDecorator(DURATION_IN_MINUTES));
153 provider.registerDecorator(DURATION_IN_DECIMAL_HOURS, new DurationDecorator(DURATION_IN_DECIMAL_HOURS));
154 provider.registerDecorator(TIME_IN_HOURS_MINUTES, new TimeDecorator());
155 provider.registerDecorator(File.class, "${absolutePath}$s", TOKEN_SEPARATOR, SEPARATOR);
156 }
157
158 private class TaxonDecorator extends Decorator<TaxonDTO> {
159
160 TaxonDecorator() {
161 super(TaxonDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR, false);
162 setUseCache(true);
163 }
164 }
165
166 private class TaxonWithCitationDecorator extends Decorator<TaxonDTO> {
167
168 TaxonWithCitationDecorator() {
169 super(TaxonDTO.class, "${name}$s#${citation}$s", TOKEN_SEPARATOR, " ", false);
170 setUseCache(true);
171 }
172
173 @Override
174 protected Object getValue(TaxonDTO bean, String token) {
175
176 if ("citation".equals(token)) {
177 if (bean.getCitation() == null) {
178 return "";
179 }
180 String citation = bean.getCitation().getName();
181 if (citation.startsWith("(")) {
182 return citation;
183 }
184 return String.format("(%s)", citation);
185 }
186
187 return super.getValue(bean, token);
188 }
189 }
190
191 private class TaxonWithReferentDecorator extends Decorator<TaxonDTO> {
192
193 TaxonWithReferentDecorator() {
194 super(TaxonDTO.class, "${name}$s#${referent}$s", TOKEN_SEPARATOR, "", false);
195 setUseCache(true);
196 }
197
198 @Override
199 protected Object getValue(TaxonDTO bean, String token) {
200
201 if ("referent".equals(token)) {
202
203 if (bean.isReferent()) {
204 return "";
205 }
206
207 return String.format(" = %s", bean.getReferenceTaxon() == null ? "[unknown referent]" : bean.getReferenceTaxon().getName());
208 }
209
210 return super.getValue(bean, token);
211 }
212 }
213
214 private class TaxonWithCitationAndReferentDecorator extends Decorator<TaxonDTO> {
215
216 TaxonWithCitationAndReferentDecorator() {
217 super(TaxonDTO.class, "${name}$s#${citation}$s#${referent}$s", TOKEN_SEPARATOR, " ", false);
218 setUseCache(true);
219 }
220
221 @Override
222 protected Object getValue(TaxonDTO bean, String token) {
223
224 if ("citation".equals(token)) {
225 if (bean.getCitation() == null) {
226 return "";
227 }
228 String citation = bean.getCitation().getName();
229 if (citation.startsWith("(")) {
230 return citation;
231 }
232 return String.format("(%s)", citation);
233
234 } else if ("referent".equals(token)) {
235
236 if (bean.isReferent()) {
237 return "";
238 }
239
240 return String.format("= %s", bean.getReferenceTaxon() == null ? "[unknown referent]" : bean.getReferenceTaxon().getName());
241 }
242
243
244 return super.getValue(bean, token);
245 }
246 }
247
248 class PMFMNameDecorator extends Decorator<PmfmDTO> {
249
250 static final String TOKEN_NAME = "name";
251
252 PMFMNameDecorator() {
253 this("${" + TOKEN_NAME + "}$s");
254 }
255
256 PMFMNameDecorator(String expression) {
257 this(expression, SEPARATOR);
258 }
259
260 PMFMNameDecorator(String expression, String separatorReplacement) {
261 super(PmfmDTO.class, expression, TOKEN_SEPARATOR, separatorReplacement, true);
262 }
263
264 @Override
265 protected Object getValue(PmfmDTO bean, String token) {
266
267 if (TOKEN_NAME.equals(token)) {
268
269
270 if (StringUtils.isBlank(bean.getName())) {
271 return bean.getParameter() != null ? bean.getParameter().getName() : null;
272 }
273
274 return bean.getName();
275 }
276
277 return super.getValue(bean, token);
278 }
279 }
280
281 private class PMFMDecorator extends PMFMNameDecorator {
282
283 PMFMDecorator() {
284 super("${" + TOKEN_NAME + "}$s#${parameter/transcribedCode}$s#${matrix/name}$s#${fraction/name}$s#${method/name}$s#${unit/symbol}$s");
285 }
286 }
287
288 private class PMFMNameWithIdDecorator extends PMFMNameDecorator {
289
290 PMFMNameWithIdDecorator() {
291
292 super("${" + TOKEN_NAME + "}$s#${parameter/transcribedCode}$s#${matrix/name}$s#${fraction/name}$s#${method/name}$s#${unit/symbol}$s#${id}$s");
293 }
294 }
295
296 private class PMFMNameWithUnitDecorator extends PMFMNameDecorator {
297
298 int noUnitId;
299 boolean checkConfig = false;
300
301 PMFMNameWithUnitDecorator() {
302 super("${" + TOKEN_NAME + "}$s#${unit/symbol}$s", "");
303 }
304
305 @Override
306 protected Object getValue(PmfmDTO bean, String token) {
307
308 if ("unit/symbol".equals(token)) {
309
310 if (!checkConfig) {
311 DaliConfiguration config = DaliConfiguration.getInstance();
312 noUnitId = config.getNoUnitId();
313 checkConfig = true;
314 }
315
316
317 if (bean.getUnit() == null || bean.getUnit().getId() == noUnitId) {
318 return "";
319 }
320
321 return String.format(" (%s)", super.getValue(bean, token));
322 }
323
324 return super.getValue(bean, token);
325 }
326 }
327
328
329
330
331
332 private class SortedQualitativeValueDecorator extends Decorator<QualitativeValueDTO> {
333
334 SortedQualitativeValueDecorator() {
335 super(QualitativeValueDTO.class, "${name}$s", TOKEN_SEPARATOR, SEPARATOR, false);
336
337 context.setComparator((o1, o2) ->
338 AlphanumericComparator.instance().compare(
339 SortedQualitativeValueDecorator.this.toString(o1),
340 SortedQualitativeValueDecorator.this.toString(o2)
341 ));
342 }
343 }
344
345
346
347
348 private class LightSurveyVODecorator extends Decorator<LightSurveyVO> {
349
350 private static final String SEPARATOR = " - ";
351
352
353
354
355 LightSurveyVODecorator() {
356 super(LightSurveyVO.class, "${surveyId}$s", "", "", false);
357 }
358
359 @Override
360 protected Object getValue(final LightSurveyVO bean, final String token) {
361 final StringBuilder result = new StringBuilder(20);
362
363
364 if (bean.getMonitoringLocation() != null) {
365 result.append(bean.getMonitoringLocation().getLabel());
366 result.append(SEPARATOR);
367 result.append(bean.getMonitoringLocation().getName());
368 result.append(SEPARATOR);
369 }
370
371
372 String dateStr = Dates.formatDate(bean.getSurveyDt(), DaliConfiguration.getInstance().getDateFormat());
373 result.append(dateStr);
374
375
376 if (ArrayUtils.isNotEmpty(bean.getPrograms())) {
377 for (ProgramVO program : bean.getPrograms()) {
378 result.append(SEPARATOR);
379 result.append(program.getProgCd());
380 }
381 }
382
383 return result.toString();
384 }
385 }
386
387
388
389
390 private class SamplingOperationDecorator extends Decorator<SamplingOperationDTO> {
391
392 private static final String SEPARATOR = " - ";
393
394
395
396
397 SamplingOperationDecorator() {
398 super(SamplingOperationDTO.class, "${name}$s", "", "", false);
399 }
400
401 @Override
402 protected Object getValue(final SamplingOperationDTO bean, final String token) {
403
404 return bean.getName() +
405 SEPARATOR +
406 Times.secondsToString(bean.getTime()) +
407 SEPARATOR +
408 bean.getSamplingEquipment().getName();
409 }
410 }
411
412
413
414
415 private class TimeDecorator extends Decorator<Integer> {
416
417 TimeDecorator() {
418 super(Integer.class, "${time}$s", "", "", false);
419 }
420
421 @Override
422 protected Object getValue(final Integer bean, final String token) {
423 return Times.secondsToString(bean);
424 }
425 }
426
427
428
429
430 private class DurationDecorator extends Decorator<Number> {
431
432 private final String type;
433
434 DurationDecorator(String type) {
435 super(Number.class, "${duration}$s", "", "", false);
436 this.type = type;
437 }
438
439 @Override
440 protected Object getValue(final Number number, final String token) {
441
442 if (number == null) {
443 return "null";
444 }
445
446 int duration = 0;
447 switch (type) {
448 case DURATION_IN_MINUTES:
449
450 duration = number.intValue();
451 break;
452
453 case DURATION_IN_DECIMAL_HOURS:
454
455 duration = (int) Math.round(number.doubleValue() * 60);
456 break;
457
458 default:
459 break;
460 }
461
462 if (duration < 0) {
463 return "< 0";
464 }
465 long days = TimeUnit.MINUTES.toDays(duration);
466 duration -= TimeUnit.DAYS.toMinutes(days);
467 long hours = TimeUnit.MINUTES.toHours(duration);
468 duration -= TimeUnit.HOURS.toMinutes(hours);
469 long minutes = TimeUnit.MINUTES.toMinutes(duration);
470
471 StringBuilder sb = new StringBuilder(64);
472 if (days > 0) {
473 sb.append(days);
474 sb.append("j ");
475 }
476 if (hours > 0) {
477 sb.append(hours);
478 sb.append("h ");
479 } else if (minutes > 0) {
480 sb.append("0h ");
481 }
482 sb.append(minutes);
483 sb.append("m");
484 return sb.toString();
485 }
486 }
487
488 private class SynchroTableWithCountDecorator extends Decorator<SynchroTableDTO> {
489
490 private final String type;
491
492 SynchroTableWithCountDecorator(String type) {
493 super(SynchroTableDTO.class, "${name}$s", "", "", false);
494 this.type = type;
495 Assert.isTrue(type == null || type.equals(WITH_COUNT), "unknown type for this decorator. Expected: null or 'withCount'");
496 }
497
498 SynchroTableWithCountDecorator() {
499 super(SynchroTableDTO.class, "${name}$s", "", "", false);
500 this.type = null;
501 }
502
503 @Override
504 protected Object getValue(SynchroTableDTO bean, String token) {
505
506
507 String decoratedTableName = t("quadrige3.table." + bean.getName());
508 if (decoratedTableName.startsWith("quadrige3.table")) {
509
510 decoratedTableName = bean.getName();
511 }
512
513 if (type == null) {
514 return decoratedTableName;
515 }
516
517
518 int nbTotal = bean.sizeRows();
519
520 return String.format("%s (%s)",
521 decoratedTableName,
522 nbTotal);
523 }
524
525 }
526
527
528 private class CollectionSizeDecorator extends Decorator<BaseReferentialDTO> {
529
530 CollectionSizeDecorator() {
531 super(BaseReferentialDTO.class, "${size}$s", "", "", false);
532 }
533
534 @Override
535 public String toString(Object object) {
536
537 return String.valueOf(CollectionUtils.size(object));
538 }
539
540 @Override
541 protected Object onNullValue(BaseReferentialDTO bean, String token) {
542 return "0";
543 }
544 }
545
546 }