View Javadoc
1   package fr.ifremer.tutti.service;
2   
3   /*
4    * #%L
5    * Tutti :: Service
6    * %%
7    * Copyright (C) 2012 - 2014 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  import com.google.common.collect.Sets;
26  import fr.ifremer.tutti.LabelAware;
27  import fr.ifremer.tutti.persistence.entities.data.Attachment;
28  import fr.ifremer.tutti.persistence.entities.data.Cruise;
29  import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
30  import fr.ifremer.tutti.persistence.entities.data.Program;
31  import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModelEntry;
32  import fr.ifremer.tutti.persistence.entities.protocol.CaracteristicType;
33  import fr.ifremer.tutti.persistence.entities.protocol.Rtp;
34  import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol;
35  import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol;
36  import fr.ifremer.tutti.persistence.entities.protocol.Zone;
37  import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
38  import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue;
39  import fr.ifremer.tutti.persistence.entities.referential.Gear;
40  import fr.ifremer.tutti.persistence.entities.referential.Person;
41  import fr.ifremer.tutti.persistence.entities.referential.Species;
42  import fr.ifremer.tutti.persistence.entities.referential.TuttiLocation;
43  import fr.ifremer.tutti.persistence.entities.referential.Vessel;
44  import org.apache.commons.lang3.StringUtils;
45  import org.nuiton.decorator.Decorator;
46  import org.nuiton.decorator.DecoratorProvider;
47  
48  import java.io.File;
49  import java.text.DecimalFormat;
50  import java.text.DecimalFormatSymbols;
51  import java.util.Comparator;
52  
53  import static org.nuiton.i18n.I18n.n;
54  import static org.nuiton.i18n.I18n.t;
55  
56  /**
57   * Tutti decorator service.
58   *
59   * @author Tony Chemit - chemit@codelutin.com
60   * @since 0.1
61   */
62  public class DecoratorService extends AbstractTuttiService {
63  
64      public static final String CARACTERISTIC_WITH_UNIT = "withUnit";
65  
66      public static final String CARACTERISTIC_PARAMETER_ONLY_WITH_UNIT = "parameterOnlyWithUnit";
67  
68      public static final String CARACTERISTIC_PARAMETER_ONLY = "parameterOnly";
69  
70      public static final String WITH_SURVEY_CODE = "withSurveyCode";
71  
72      public static final String WITH_SURVEY_CODE_NO_NAME = "withSurveyCodeNoName";
73  
74      public static final String FROM_PROTOCOL = "fromProtocol";
75  
76      public static final String GEAR_WITH_RANK_ORDER = "gearWithrankOrder";
77  
78      public static final String ONLY_NAME = "onlyName";
79  
80      public static final String FILE_NAME_COMPATIBLE = "fileNameCompatible";
81  
82      public static final String SPACE_EVERY_3_DIGIT = "spaceEvery3Digit";
83  
84      public static final String MATURITY = "maturity";
85  
86      public static final String NULL_INFINITE = "nullInfinite";
87  
88      public static final String SEPARATOR = "#";
89  
90      public static final Comparator<FishingOperation> FISHING_OPERATION_COMPARATOR_BY_GEAR_SHOOTING_START_DATE = (o1, o2) -> o1.getGearShootingStartDate().compareTo(o2.getGearShootingStartDate());
91  
92  
93      /** Delegate decorator provider. */
94      protected DecoratorProvider decoratorProvider;
95  
96      public <O> Decorator<O> getDecorator(O object) {
97          return decoratorProvider.getDecorator(object);
98      }
99  
100     public <O> Decorator<O> getDecorator(O object, String name) {
101         return decoratorProvider.getDecorator(object, name);
102     }
103 
104     public <O> Decorator<O> getDecoratorByType(Class<O> type) {
105         return decoratorProvider.getDecoratorByType(type);
106     }
107 
108     public <O> Decorator<O> getDecoratorByType(Class<O> type, String name) {
109         return decoratorProvider.getDecoratorByType(type, name);
110     }
111 
112     @Override
113     public void setServiceContext(TuttiServiceContext context) {
114         super.setServiceContext(context);
115 
116         decoratorProvider = new DecoratorProvider() {
117             @Override
118             protected void loadDecorators() {
119 
120                 registerTuttiDecorator(SampleCategoryModelEntry.class, "${label}$s", SEPARATOR, " - ");
121                 registerTuttiDecorator(TuttiLocation.class, "${label}$s#${name}$s", SEPARATOR, " - ");
122                 registerTuttiDecorator(Cruise.class, "${name}$s", SEPARATOR, " - ");
123                 registerTuttiDecorator(TuttiProtocol.class, "${name}$s", SEPARATOR, " - ");
124                 registerTuttiDecorator(Rtp.class, "${a}$s#${b}$s", SEPARATOR, " - ");
125                 registerTuttiDecorator(Zone.class, "${label}$s", SEPARATOR, " - ");
126                 registerDecorator(new FishingOperationDecorator());
127                 registerTuttiDecorator(FishingOperation.class, FILE_NAME_COMPATIBLE, "${stationNumber}$s#${fishingOperationNumber}$s#${multirigAggregation}$s#${gearShootingStartDate}$td%4$tm%4$tY", SEPARATOR, "-");
128                 registerTuttiDecorator(Gear.class, "${label}$s#${name}$s", SEPARATOR, " - ");
129                 registerTuttiDecorator(Gear.class, GEAR_WITH_RANK_ORDER, "${rankOrder}$d#${label}$s#${name}$s", SEPARATOR, " - ");
130                 registerTuttiDecorator(Person.class, "${firstName}$s#${lastName}$s#${department}$s", SEPARATOR, " ");
131                 registerTuttiDecorator(Caracteristic.class, "${parameterName}$s#${matrixName}$s#${fractionName}$s#${methodName}$s", SEPARATOR, " - ");
132                 registerTuttiDecorator(Caracteristic.class, CARACTERISTIC_PARAMETER_ONLY, "${parameterName}$s", SEPARATOR, " - ");
133                 registerDecorator(CARACTERISTIC_PARAMETER_ONLY_WITH_UNIT, new SimpleCaracteristicDecorator("${parameterName}$s"));
134 
135                 registerTuttiDecorator(CaracteristicQualitativeValue.class, "${description}$s", SEPARATOR, " - ");
136                 registerDecorator(new Decorator<CaracteristicType>(CaracteristicType.class) {
137                     @Override
138                     public String toString(Object bean) {
139                         return bean == null ? "" : t("tutti.caracteristicType." + bean.toString());
140                     }
141                 });
142                 registerTuttiDecorator(SpeciesProtocol.class, "${speciesReferenceTaxonId}", SEPARATOR, " - ");
143                 registerTuttiDecorator(Attachment.class, "${name}$s", SEPARATOR, " - ");
144                 registerTuttiDecorator(LabelAware.class, "${label}$s", SEPARATOR, " - ");
145                 registerTuttiDecorator(File.class, "${name}$s", SEPARATOR, " - ");
146                 registerDecorator(new Decorator<Float>(Float.class) {
147                     private static final long serialVersionUID = 1L;
148 
149                     @Override
150                     public String toString(Object bean) {
151                         return bean == null ? "" : String.valueOf(bean);
152                     }
153                 });
154                 registerDecorator(new Decorator<Number>(Number.class) {
155                     private static final long serialVersionUID = 1L;
156 
157                     @Override
158                     public String toString(Object bean) {
159                         return bean == null ? "" : String.valueOf(bean);
160                     }
161                 });
162                 registerDecorator(SPACE_EVERY_3_DIGIT, new SpaceEvery3DigitDecorator());
163                 registerDecorator(NULL_INFINITE, new Decorator<Integer>(Integer.class) {
164                     private static final long serialVersionUID = 1L;
165 
166                     @Override
167                     public String toString(Object bean) {
168                         return bean == null ? t("tutti.decorator.null.infinite") : String.valueOf(bean);
169                     }
170                 });
171                 registerDecorator(MATURITY, new MaturityDecorator());
172                 registerDecorator(new VesselDecorator());
173                 registerDecorator(new ProgramDecorator());
174                 registerTuttiDecorator(Program.class, ONLY_NAME, "${name}$s", SEPARATOR, " - ");
175 
176                 registerDecorator(new SpeciesDecorator());
177                 registerDecorator(WITH_SURVEY_CODE, new SpeciesDecoratorWithSurveyCode(true));
178                 registerDecorator(WITH_SURVEY_CODE_NO_NAME, new SpeciesDecoratorWithSurveyCode(false));
179                 registerDecorator(FROM_PROTOCOL, new SpeciesFromProtocolDecorator());
180                 registerDecorator(CARACTERISTIC_WITH_UNIT, new SimpleCaracteristicDecorator("${parameterName}$s#${matrixName}$s#${fractionName}$s#${methodName}$s"));
181 
182                 TuttiDecorator<FishingOperation> fishingOperationTuttiDecorator = (TuttiDecorator<FishingOperation>) getDecoratorByType(FishingOperation.class);
183                 fishingOperationTuttiDecorator.setSortOnlyOnSelectedContext(true);
184                 fishingOperationTuttiDecorator.setSortOnlyOnSelectedContextTokens(Sets.newHashSet(FishingOperation.PROPERTY_FISHING_OPERATION_NUMBER));
185             }
186 
187             public void registerTuttiDecorator(Class<?> klass, String expression, String separator, String separatorReplacement) {
188                 super.registerDecorator(TuttiDecorator.newDecorator(klass, expression, separator, separatorReplacement));
189             }
190 
191             public void registerTuttiDecorator(Class<?> klass, String name, String expression, String separator, String separatorReplacement) {
192                 super.registerDecorator(name, TuttiDecorator.newDecorator(klass, expression, separator, separatorReplacement));
193             }
194         };
195     }
196 
197     static {
198         n("tutti.property.protocol");
199         n("tutti.property.label");
200         n("tutti.property.name");
201         n("tutti.property.person");
202         n("tutti.property.firstName");
203         n("tutti.property.lastName");
204         n("tutti.property.department");
205         n("tutti.property.stationNumber");
206         n("tutti.property.fishingOperationNumber");
207         n("tutti.property.gearShootingStartDate");
208         n("tutti.property.internationalRegistrationCode");
209         n("tutti.property.date");
210         n("tutti.property.program");
211         n("tutti.property.parameterName");
212         n("tutti.property.matrixName");
213         n("tutti.property.fractionName");
214         n("tutti.property.methodName");
215         n("tutti.property.cruise");
216         n("tutti.property.fishingOperation");
217         n("tutti.property.fishingOperationLocation");
218         n("tutti.property.tuttiLocation");
219         n("tutti.property.zone");
220         n("tutti.property.vessel");
221         n("tutti.property.country");
222         n("tutti.property.gear");
223         n("tutti.property.user");
224         n("tutti.property.strata");
225         n("tutti.property.refTaxCode");
226         n("tutti.property.surveyCode");
227         n("tutti.property.rankOrder");
228         n("tutti.property.species");
229         n("tutti.property.genusSpecies");
230         n("tutti.property.sortedUnsortedCategory");
231         n("tutti.property.marineLitterCategory");
232         n("tutti.property.attachment");
233         n("tutti.property.multirigAggregation");
234         n("tutti.property.caracteristic");
235         n("tutti.caracteristicType.GEAR_USE_FEATURE");
236         n("tutti.caracteristicType.INDIVIDUAL_OBSERVATION");
237         n("tutti.caracteristicType.lengthStep");
238         n("tutti.caracteristicType.VESSEL_USE_FEATURE");
239     }
240 
241     public static class SpeciesDecorator extends TuttiDecorator<Species> implements Cloneable {
242 
243         private static final long serialVersionUID = 1L;
244 
245         public SpeciesDecorator() throws IllegalArgumentException, NullPointerException {
246             super(Species.class, "${refTaxCode}$s#${name}$s", DecoratorService.SEPARATOR, " - ");
247         }
248 
249         @Override
250         protected Object onNullValue(Species bean, String token) {
251             Object result = null;
252             if (Species.PROPERTY_REF_TAX_CODE.equals(token)) {
253                 result = t("tutti.propety.no.species.speciesCode");
254             }
255             return result;
256         }
257     }
258 
259     public static class SpeciesDecoratorWithSurveyCode extends TuttiDecorator<Species> implements Cloneable {
260 
261         private static final long serialVersionUID = 1L;
262 
263         public SpeciesDecoratorWithSurveyCode() throws IllegalArgumentException, NullPointerException {
264             this(true);
265         }
266 
267         public SpeciesDecoratorWithSurveyCode(boolean showName) throws IllegalArgumentException, NullPointerException {
268             super(Species.class, showName ? "${surveyCode}$s#${name}$s" : "${surveyCode}$s", DecoratorService.SEPARATOR, " - ");
269         }
270 
271         @Override
272         protected Object onNullValue(Species bean, String token) {
273             Object result = null;
274             if (Species.PROPERTY_SURVEY_CODE.equals(token)) {
275 
276                 // try with refTaxCode
277                 result = bean.getRefTaxCode();
278 
279                 if (result == null) {
280 
281                     result = t("tutti.propety.no.species.speciesCode");
282                 }
283             }
284             return result;
285         }
286     }
287 
288     public static class SimpleCaracteristicDecorator extends TuttiDecorator<Caracteristic> implements Cloneable {
289 
290         private static final long serialVersionUID = 1L;
291 
292         public SimpleCaracteristicDecorator(String firstPart) throws IllegalArgumentException, NullPointerException {
293             super(Caracteristic.class, firstPart + "#${unit}$s", DecoratorService.SEPARATOR, " ");
294         }
295 
296         @Override
297         protected Object getValue(Caracteristic bean, String token) {
298             Object result = super.getValue(bean, token);
299 
300             if (Caracteristic.PROPERTY_UNIT.equals(token) &&
301                 StringUtils.isNotBlank((String) result)) {
302                 result = "(" + result + ")";
303             }
304             return result;
305         }
306     }
307 
308     public static class SpeciesFromProtocolDecorator extends TuttiDecorator<Species> implements Cloneable {
309 
310         private static final long serialVersionUID = 1L;
311 
312         public SpeciesFromProtocolDecorator() throws IllegalArgumentException, NullPointerException {
313             super(Species.class, "${surveyCode}$s#${name}$s", DecoratorService.SEPARATOR, " - ");
314         }
315 
316         @Override
317         protected Object getValue(Species bean, String token) {
318             Object result = super.getValue(bean, token);
319             if (Species.PROPERTY_SURVEY_CODE.equals(token) && result == null) {
320                 result = bean.getRefTaxCode();
321             }
322             return result;
323         }
324 
325         @Override
326         protected Object onNullValue(Species bean, String token) {
327             Object result;
328             if (Species.PROPERTY_SURVEY_CODE.equals(token)) {
329                 result = t("tutti.propety.no.species.speciesCode");
330 
331             } else {
332                 result = super.onNullValue(bean, token);
333             }
334             return result;
335         }
336     }
337 
338     public static class ProgramDecorator extends TuttiDecorator<Program> implements Cloneable {
339 
340         private static final long serialVersionUID = 1L;
341 
342         public ProgramDecorator() throws IllegalArgumentException, NullPointerException {
343             super(Program.class, "${name}$s#${zone}$s", DecoratorService.SEPARATOR, " - ");
344         }
345 
346         @Override
347         protected Object getValue(Program bean, String token) {
348             Object result = super.getValue(bean, token);
349             if (Program.PROPERTY_ZONE.equals(token) && result != null) {
350                 result = ((TuttiLocation) result).getLabel();
351             }
352             return result;
353         }
354 
355         @Override
356         protected Object onNullValue(Program bean, String token) {
357             Object result = null;
358             if (Program.PROPERTY_ZONE.equals(token)) {
359                 result = t("tutti.propety.no.zone");
360             }
361             return result;
362         }
363     }
364 
365     public static class VesselDecorator extends TuttiDecorator<Vessel> implements Cloneable {
366 
367         private static final long serialVersionUID = 1L;
368 
369         public VesselDecorator() throws IllegalArgumentException, NullPointerException {
370             super(Vessel.class, "${internationalRegistrationCode}$s#${name}$s", DecoratorService.SEPARATOR, " - ");
371         }
372 
373         @Override
374         protected Object getValue(Vessel bean, String token) {
375             // handle the null internationalRegistrationCode here,
376             // otherwise this will be considered null during sorting
377             Object result = super.getValue(bean, token);
378             if (Vessel.PROPERTY_INTERNATIONAL_REGISTRATION_CODE.equals(token) && result == null) {
379                 // use national registration code
380                 result = t("tutti.propety.vessel.nation.registrationCode", bean.getRegistrationCode());
381             }
382             return result;
383         }
384 
385         @Override
386         protected Object onNullValue(Vessel bean, String token) {
387             Object result = null;
388             if (Vessel.PROPERTY_NAME.equals(token)) {
389                 result = t("tutti.propety.no.vessel.name");
390             }
391             return result;
392         }
393     }
394 
395     public static class FishingOperationDecorator extends TuttiDecorator<FishingOperation> implements Cloneable {
396 
397         private static final long serialVersionUID = 1L;
398 
399         public FishingOperationDecorator() throws IllegalArgumentException, NullPointerException {
400             super(FishingOperation.class, "${stationNumber}$s#${fishingOperationNumber}$d#${multirigAggregation}$s#${gearShootingStartDate}$td/%4$tm/%4$tY", SEPARATOR, " - ");
401         }
402 
403         @Override
404         protected Comparator<FishingOperation> getComparator(int pos) {
405             Comparator<FishingOperation> comparator;
406             if (pos == 3) {
407                 comparator = FISHING_OPERATION_COMPARATOR_BY_GEAR_SHOOTING_START_DATE;
408             } else {
409                 comparator = super.getComparator(pos);
410             }
411             return comparator;
412         }
413 
414         @Override
415         protected Object onNullValue(FishingOperation bean, String token) {
416             Object result = null;
417             if (Vessel.PROPERTY_NAME.equals(token)) {
418                 result = t("tutti.propety.no.vessel.name");
419             }
420             return result;
421         }
422     }
423 
424     public static class SpaceEvery3DigitDecorator extends Decorator<String> implements Cloneable {
425 
426         DecimalFormat df;
427 
428         public SpaceEvery3DigitDecorator() throws NullPointerException {
429             super(String.class);
430             DecimalFormatSymbols symbols = new DecimalFormatSymbols();
431             symbols.setGroupingSeparator(' '); //espace insécable
432             df = new DecimalFormat("###,###", symbols);
433         }
434 
435         @Override
436         public String toString(Object bean) {
437             String s = (String) bean;
438             try {
439                 int i = Integer.parseInt(s);
440                 return df.format(i);
441 
442             } catch (NumberFormatException e) {
443                 return "";
444             }
445         }
446     }
447 
448     public static class MaturityDecorator extends Decorator<Boolean> {
449 
450         protected MaturityDecorator() {
451             super(Boolean.class);
452         }
453 
454         @Override
455         public String toString(Object bean) {
456             String result;
457 
458             if (bean == null) {
459                 result = "";
460 
461             } else {
462 
463                 Boolean maturity = (Boolean) bean;
464                 result = maturity ? t("tutti.maturity.mature") : t("tutti.maturity.immature");
465             }
466 
467             return result;
468         }
469     }
470 }