View Javadoc
1   package fr.ifremer.quadrige3.ui.core.dto;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: UI Core Common
6    * %%
7    * Copyright (C) 2017 - 2019 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Affero General Public License as published by
11   * the Free Software Foundation, either version 3 of the License, or
12   * (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 Affero General Public License
20   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21   * #L%
22   */
23  
24  import fr.ifremer.quadrige3.core.dao.referential.Status;
25  import fr.ifremer.quadrige3.core.dao.referential.StatusCode;
26  import fr.ifremer.quadrige3.core.dao.referential.UnitId;
27  import fr.ifremer.quadrige3.core.dao.technical.Assert;
28  import fr.ifremer.quadrige3.core.dao.technical.Beans;
29  import fr.ifremer.quadrige3.core.exception.QuadrigeTechnicalException;
30  import fr.ifremer.quadrige3.ui.core.dto.referential.BaseReferentialDTO;
31  import fr.ifremer.quadrige3.ui.core.dto.referential.StatusDTO;
32  import org.apache.commons.beanutils.BeanUtils;
33  import org.apache.commons.collections4.CollectionUtils;
34  import org.apache.commons.lang3.ArrayUtils;
35  import org.apache.commons.lang3.StringUtils;
36  
37  import java.lang.reflect.InvocationTargetException;
38  import java.math.BigDecimal;
39  import java.math.RoundingMode;
40  import java.sql.Array;
41  import java.sql.SQLException;
42  import java.text.DecimalFormat;
43  import java.text.DecimalFormatSymbols;
44  import java.util.*;
45  import java.util.function.Function;
46  import java.util.stream.Collectors;
47  
48  import static org.nuiton.i18n.I18n.t;
49  
50  /**
51   * useful methods around quadrige bean.
52   *
53   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
54   * <p>
55   * TODO move common methods to fr.ifremer.quadrige3.core.dao.technical.Beans
56   */
57  public class QuadrigeBeans extends Beans {
58  
59      /**
60       * Constant <code>GET_ID_STRING</code>
61       */
62      public static final Function<QuadrigeBean, String> GET_ID_STRING = input -> (input == null) ? null : input.getId().toString();
63      /**
64       * Constant <code>ID_MAPPER</code>
65       */
66      public static final Function<String, Integer> ID_MAPPER = id -> (id == null || id.isEmpty()) ? null : Integer.valueOf(id);
67      /**
68       * Constant <code>GET_CODE</code>
69       */
70      public static final Function<QuadrigeBean, String> GET_CODE = p -> (p == null) ? null : (String) getProperty(p, "code");
71      /**
72       * Constant <code>DEFAULT_DATE_FORMAT="dd/MM/yyyy"</code>
73       */
74      public static final String DEFAULT_DATE_FORMAT = "dd/MM/yyyy";
75      /**
76       * Constant <code>DEFAULT_STRING_SEPARATOR=" - "</code>
77       */
78      public static final String DEFAULT_STRING_SEPARATOR = " - ";
79      private static DecimalFormatSymbols symbols;
80      private static DecimalFormat decimalFormat;
81  
82      /**
83       * <p>Constructor for QuadrigeBeans.</p>
84       */
85      protected QuadrigeBeans() {
86          // helper class does not instantiate
87      }
88  
89      /**
90       * <p>collectIds.</p>
91       *
92       * @param collection a {@link Collection} object.
93       * @param <B>        a B object.
94       * @return a {@link List} object.
95       */
96      public static <B extends QuadrigeBean> List<Integer> collectIds(Collection<B> collection) {
97          if (CollectionUtils.isEmpty(collection)) return new ArrayList<>();
98          return collection.stream().filter(Objects::nonNull).map(QuadrigeBean::getId).filter(Objects::nonNull).collect(Collectors.toList());
99      }
100 
101     public static <B extends QuadrigeBean> List<String> collectStringIds(Collection<B> collection) {
102         if (CollectionUtils.isEmpty(collection)) return new ArrayList<>();
103         return collection.stream().filter(Objects::nonNull)
104                 .map(bean -> bean instanceof CodeOnly ? ((CodeOnly) bean).getCode() : bean.getId().toString())
105                 .filter(Objects::nonNull).collect(Collectors.toList());
106     }
107 
108     public static <B extends QuadrigeBean> String joinIds(Collection<B> collection, String separator) {
109         return String.join(separator, collectStringIds(collection));
110     }
111 
112     /**
113      * Return an ImmutableMap of list as values with each id of elements in list as key.
114      *
115      * @param beans a {@link Collection} object.
116      * @return ImmutableMap
117      */
118     public static <B extends QuadrigeBean> Map<Integer, B> mapById(Collection<B> beans) {
119         return CollectionUtils.isNotEmpty(beans)
120                 ?
121                 beans.stream().collect(Collectors.toMap(
122                                 QuadrigeBean::getId, // the key mapper
123                                 o -> o, // the value mapper (= the bean itself)
124                                 (k1, k2) -> { // if duplicates found
125                                     throw new IllegalStateException(String.format("Duplicate key %s", k1));
126                                 },
127                                 HashMap::new))
128                 : new HashMap<>();
129 //        return list != null
130 //                ? new HashMap<>(Maps.uniqueIndex(list, QuadrigeBean::getId))
131 //                : new HashMap<>();
132     }
133 
134     /**
135      * <p>findById.</p>
136      *
137      * @param <B>   a B object.
138      * @param beans a {@link Collection} object.
139      * @param id    a {@link Integer} object.
140      * @return a B object.
141      */
142     public static <B extends QuadrigeBean> B findById(Collection<B> beans, Integer id) {
143         if (CollectionUtils.isEmpty(beans) || id == null) return null;
144         return beans.stream().filter(Objects::nonNull).filter(b -> id.equals(b.getId())).findFirst().orElse(null);
145     }
146 
147     /**
148      * <p>getDecimalFormatSymbols.</p>
149      *
150      * @return a {@link DecimalFormatSymbols} object.
151      */
152     public static DecimalFormatSymbols getDecimalFormatSymbols() {
153         if (symbols == null) {
154             symbols = new DecimalFormatSymbols();
155             symbols.setDecimalSeparator('.');
156             symbols.setGroupingSeparator(' ');
157         }
158         return symbols;
159     }
160 
161     /**
162      * <p>Getter for the field <code>decimalFormat</code>.</p>
163      *
164      * @param minDecimal a int.
165      * @param maxDecimal a int.
166      * @return a {@link DecimalFormat} object.
167      */
168     public static DecimalFormat getDecimalFormat(int minDecimal, int maxDecimal) {
169         if (decimalFormat == null) {
170             decimalFormat = new DecimalFormat();
171             decimalFormat.setDecimalFormatSymbols(getDecimalFormatSymbols());
172             decimalFormat.setGroupingUsed(false);
173         }
174         decimalFormat.setMinimumFractionDigits(minDecimal);
175         decimalFormat.setMaximumFractionDigits(maxDecimal);
176         return decimalFormat;
177     }
178 
179     /**
180      * transform the string to a secured format (eg for file name):
181      * - strip accents
182      * - remove special characters
183      *
184      * @param text to transform
185      * @return transformed string
186      */
187     public static String toSecuredString(String text) {
188         if (text == null) return null;
189         // remove special characters
190         String result = text.trim().replaceAll("[.,:;'\"()\\[\\]{}?!^=+/\\\\#~%²&|`¨@$£€¤µ*§]+", "");
191         // transform accented characters
192         return StringUtils.stripAccents(result);
193     }
194 
195     /**
196      * transform the string to a fully secured format (eg for extraction):
197      * - strip accents
198      * - remove article with apostrophe
199      * - remove special characters
200      * - replace space by underscore
201      *
202      * @param text to transform
203      * @return transformed string
204      */
205     public static String toFullySecuredString(String text) {
206         if (text == null) return null;
207         // remove d' l'
208         String result = text.replaceAll("[a-zA-Z]'", "");
209         // transform accented characters and remove special characters
210         result = toSecuredString(result);
211         // replace space by underscore
212         return result != null ? result.replaceAll(" ", "_") : null;
213     }
214 
215     /**
216      * <p>clone.</p>
217      *
218      * @param bean a B object.
219      * @param <B>  a B object.
220      * @return a T object.
221      * @throws QuadrigeTechnicalException if any.
222      */
223     @SuppressWarnings("unchecked")
224     public static <B extends QuadrigeBean> B clone(final B bean) throws QuadrigeTechnicalException {
225         if (bean == null) return null;
226         try {
227             // Clone bean
228             return (B) BeanUtils.cloneBean(bean);
229         } catch (final IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
230             throw new QuadrigeTechnicalException(t("quadrige.error.exception.duplicateBean"), e);
231         }
232     }
233 
234     public static <B extends QuadrigeBean> List<B> clone(final Collection<B> beans) {
235         if (beans == null) return null;
236         return beans.stream().map(QuadrigeBeans::clone).collect(Collectors.toList());
237     }
238 
239     public static <B extends QuadrigeBean> Set<B> clone(final Set<B> beans) {
240         if (beans == null) return null;
241         return beans.stream().map(QuadrigeBeans::clone).collect(Collectors.toSet());
242     }
243 
244     public static BigDecimal convertLengthValue(BigDecimal length, int fromUnitId, int toUnitId) {
245 
246         if (length == null) {
247             return null;
248         }
249         if (length.intValue() == 0) {
250             return BigDecimal.valueOf(0);
251         }
252         if (fromUnitId == toUnitId) {
253             return length;
254         }
255 
256         UnitId[] availableUnits = new UnitId[]{UnitId.METER, UnitId.CENTIMENTER, UnitId.MILLIMETER, UnitId.MICROMETER};
257         UnitId fromUnit;
258         UnitId toUnit;
259         try {
260             fromUnit = UnitId.fromValue(fromUnitId);
261             if (!ArrayUtils.contains(availableUnits, fromUnit)) {
262                 throw new IllegalArgumentException();
263             }
264         } catch (IllegalArgumentException e) {
265             throw new QuadrigeTechnicalException(t("quadrige.error.length.conversion", fromUnitId));
266         }
267         try {
268             toUnit = UnitId.fromValue(toUnitId);
269             if (!ArrayUtils.contains(availableUnits, toUnit)) {
270                 throw new IllegalArgumentException();
271             }
272         } catch (IllegalArgumentException e) {
273             throw new QuadrigeTechnicalException(t("quadrige.error.length.conversion", toUnitId));
274         }
275 
276         Map<UnitId, BigDecimal> conversionMap = new HashMap<>();
277         conversionMap.put(UnitId.METER, BigDecimal.valueOf(1));
278         conversionMap.put(UnitId.CENTIMENTER, BigDecimal.valueOf(100));
279         conversionMap.put(UnitId.MILLIMETER, BigDecimal.valueOf(1000));
280         conversionMap.put(UnitId.MICROMETER, BigDecimal.valueOf(1000L * 1000));
281 
282         return length.multiply(conversionMap.get(toUnit)).divide(conversionMap.get(fromUnit), RoundingMode.FLOOR);
283     }
284 
285     public static Integer toInteger(BigDecimal bigDecimal) {
286         return bigDecimal != null ? bigDecimal.intValue() : null;
287     }
288 
289     public static Double toDouble(BigDecimal bigDecimal) {
290         return bigDecimal != null ? bigDecimal.doubleValue() : null;
291     }
292 
293     /**
294      * Method used as external function for HSQLDB
295      * see fr.ifremer.dali.service.extraction.ExtractionServiceImpl#createConcatDistinctFunction(java.lang.String, java.lang.String)
296      *
297      * @param array     the input array (any type)
298      * @param separator the separator to use
299      * @return the unified string
300      */
301     @SuppressWarnings(value = "unused")
302     public static String getUnifiedSQLString(Array array, String separator) {
303 
304         try {
305 
306             return getUnifiedString(
307                     Arrays.stream((Object[]) array.getArray())
308                             .filter(Objects::nonNull)
309                             .map(Object::toString)
310                             .collect(Collectors.toList()),
311                     separator);
312 
313         } catch (SQLException e) {
314 
315             return "";
316         }
317     }
318 
319     /**
320      * Get the unified string from a list of string
321      * <p>
322      * It concat all unique occurrence of string in the list.
323      * If an item already contains a joined string with the separator, the inner items are splitted before.
324      *
325      * @param strings   the list to proceed
326      * @param separator the separator to use
327      * @return the unified string
328      */
329     public static String getUnifiedString(List<String> strings, String separator) {
330 
331         Set<String> stringSet = new LinkedHashSet<>();
332 
333         for (String string : strings) {
334             if (StringUtils.isNotBlank(string)) {
335 
336                 // split already joined comment
337                 if (string.contains(separator)) {
338                     List<String> subComments = split(string, separator);
339                     stringSet.addAll(subComments);
340                 } else {
341                     stringSet.add(string);
342                 }
343             }
344         }
345 
346         return stringSet.stream().filter(Objects::nonNull).collect(Collectors.joining(separator));
347 //        return Joiner.on(separator).skipNulls().join(stringSet);
348     }
349 
350     /**
351      * return true only if bean has blocking errors (control errors and warnings are not blocking)
352      *
353      * @param bean a {@link ErrorAware} object.
354      * @return a boolean.
355      */
356     public static boolean hasNoBlockingError(ErrorAware bean) {
357         if (bean != null && CollectionUtils.isNotEmpty(bean.getErrors())) {
358             for (ErrorDTO error : bean.getErrors()) {
359                 if (error.isError() && !error.isControl()) {
360                     return false;
361                 }
362             }
363         }
364         return true;
365     }
366 
367     /**
368      * <p>removeBlockingErrors.</p>
369      *
370      * @param bean a {@link ErrorAware} object.
371      */
372     public static void removeBlockingErrors(ErrorAware bean) {
373         bean.getErrors().removeIf(error -> !error.isControl());
374     }
375 
376     /**
377      * <p>getErrors.</p>
378      *
379      * @param bean        a {@link ErrorAware} object.
380      * @param controlOnly a {@link Boolean} object.
381      * @return a {@link List} object.
382      */
383     public static List<ErrorDTO> getErrors(ErrorAware bean, final Boolean controlOnly) {
384         if (bean == null || CollectionUtils.isEmpty(bean.getErrors())) {
385             return new ArrayList<>();
386         }
387         return filterCollection(bean.getErrors(), error -> error.isError() && (controlOnly == null || (controlOnly == error.isControl())));
388     }
389 
390     /**
391      * <p>getErrorMessages.</p>
392      *
393      * @param bean a {@link ErrorAware} object.
394      * @return a {@link List} object.
395      */
396     public static List<String> getErrorMessages(ErrorAware bean) {
397         return collectProperties(getErrors(bean, null), ErrorDTO.PROPERTY_MESSAGE);
398     }
399 
400     /**
401      * <p>getErrors.</p>
402      *
403      * @param bean         a {@link ErrorAware} object.
404      * @param propertyName a {@link String} object.
405      * @param pmfmId       a {@link Integer} object.
406      * @param controlOnly  a {@link Boolean} object.
407      * @return a {@link List} object.
408      */
409     public static List<ErrorDTO> getErrors(ErrorAware bean, final String propertyName, final Integer pmfmId, final Boolean controlOnly) {
410         if (bean == null || CollectionUtils.isEmpty(bean.getErrors())) {
411             return new ArrayList<>();
412         }
413         return filterCollection(bean.getErrors(), error -> error.isError()
414                 && (controlOnly == null || (controlOnly == error.isControl()))
415                 && error.containsPropertyName(propertyName)
416                 && (pmfmId == null || pmfmId.equals(error.getPmfmId()))
417         );
418     }
419 
420     /**
421      * <p>getErrorMessages.</p>
422      *
423      * @param bean         a {@link ErrorAware} object.
424      * @param propertyName a {@link String} object.
425      * @param pmfmId       a {@link Integer} object.
426      * @return a {@link List} object.
427      */
428     public static List<String> getErrorMessages(ErrorAware bean, String propertyName, Integer pmfmId) {
429         return collectProperties(getErrors(bean, propertyName, pmfmId, null), ErrorDTO.PROPERTY_MESSAGE);
430     }
431 
432     /**
433      * <p>getWarnings.</p>
434      *
435      * @param bean        a {@link ErrorAware} object.
436      * @param controlOnly a {@link Boolean} object.
437      * @return a {@link List} object.
438      */
439     public static List<ErrorDTO> getWarnings(ErrorAware bean, final Boolean controlOnly) {
440         if (bean == null || CollectionUtils.isEmpty(bean.getErrors())) {
441             return new ArrayList<>();
442         }
443         return filterCollection(bean.getErrors(), error -> error.isWarning() && (controlOnly == null || (controlOnly == error.isControl())));
444     }
445 
446     /**
447      * <p>getWarningMessages.</p>
448      *
449      * @param bean a {@link ErrorAware} object.
450      * @return a {@link List} object.
451      */
452     public static List<String> getWarningMessages(ErrorAware bean) {
453         return collectProperties(getWarnings(bean, null), ErrorDTO.PROPERTY_MESSAGE);
454     }
455 
456     /**
457      * <p>getWarnings.</p>
458      *
459      * @param bean         a {@link ErrorAware} object.
460      * @param propertyName a {@link String} object.
461      * @param pmfmId       a {@link Integer} object.
462      * @param controlOnly  a {@link Boolean} object.
463      * @return a {@link List} object.
464      */
465     public static List<ErrorDTO> getWarnings(ErrorAware bean, final String propertyName, final Integer pmfmId, final Boolean controlOnly) {
466         if (bean == null || CollectionUtils.isEmpty(bean.getErrors())
467                 // if an error is found, return empty list because error is priority
468                 || !getErrors(bean, propertyName, pmfmId, controlOnly).isEmpty()) {
469             return new ArrayList<>();
470         }
471         return filterCollection(bean.getErrors(), error -> error.isWarning()
472                 && (controlOnly == null || (controlOnly == error.isControl()))
473                 && error.containsPropertyName(propertyName)
474                 && (pmfmId == null || pmfmId.equals(error.getPmfmId())));
475     }
476 
477     /**
478      * <p>getWarningMessages.</p>
479      *
480      * @param bean         a {@link ErrorAware} object.
481      * @param propertyName a {@link String} object.
482      * @param pmfmId       a {@link Integer} object.
483      * @return a {@link List} object.
484      */
485     public static List<String> getWarningMessages(ErrorAware bean, String propertyName, Integer pmfmId) {
486         return collectProperties(getWarnings(bean, propertyName, pmfmId, null), ErrorDTO.PROPERTY_MESSAGE);
487     }
488 
489     /**
490      * <p>addError.</p>
491      *
492      * @param bean       a {@link ErrorAware} object.
493      * @param message    a {@link String} object.
494      * @param properties a {@link String} object.
495      */
496     public static void addError(ErrorAware bean, String message, String... properties) {
497         addError(bean, message, null, properties);
498     }
499 
500     /**
501      * <p>addError.</p>
502      *
503      * @param bean       a {@link ErrorAware} object.
504      * @param message    a {@link String} object.
505      * @param pmfmId     a {@link Integer} object.
506      * @param properties a {@link String} object.
507      */
508     public static void addError(ErrorAware bean, String message, Integer pmfmId, String... properties) {
509         addErrorDTOToBean(bean, false, message, pmfmId, properties);
510     }
511 
512     /**
513      * <p>addWarning.</p>
514      *
515      * @param bean       a {@link ErrorAware} object.
516      * @param message    a {@link String} object.
517      * @param properties a {@link String} object.
518      */
519     public static void addWarning(ErrorAware bean, String message, String... properties) {
520         addWarning(bean, message, null, properties);
521     }
522 
523     /**
524      * <p>addWarning.</p>
525      *
526      * @param bean       a {@link ErrorAware} object.
527      * @param message    a {@link String} object.
528      * @param pmfmId     a {@link Integer} object.
529      * @param properties a {@link String} object.
530      */
531     public static void addWarning(ErrorAware bean, String message, Integer pmfmId, String... properties) {
532         addErrorDTOToBean(bean, true, message, pmfmId, properties);
533     }
534 
535     private static void addErrorDTOToBean(ErrorAware bean, boolean warning, String message, Integer pmfmId, String... properties) {
536         ErrorDTO error = QuadrigeBeanFactory.newErrorDTO();
537         error.setError(!warning);
538         error.setWarning(warning);
539         error.setMessage(message);
540         error.setPropertyName(properties != null ? Arrays.asList(properties) : null);
541         error.setPmfmId(pmfmId);
542         bean.getErrors().add(error);
543     }
544 
545     /**
546      * <p>addUniqueErrors.</p>
547      *
548      * @param bean   a {@link ErrorAware} object.
549      * @param errors a {@link Collection} object.
550      */
551     public static void addUniqueErrors(ErrorAware bean, Collection<ErrorDTO> errors) {
552 
553         if (CollectionUtils.isNotEmpty(errors)) {
554             for (ErrorDTO errorToAdd : errors) {
555                 boolean canAdd = true;
556                 for (ErrorDTO existingError : bean.getErrors()) {
557                     if (isErrorEquals(errorToAdd, existingError)) {
558                         canAdd = false;
559                         break;
560                     }
561                 }
562                 if (canAdd) {
563                     bean.getErrors().add(errorToAdd);
564                 }
565             }
566         }
567 
568     }
569 
570     private static boolean isErrorEquals(ErrorDTO error1, ErrorDTO error2) {
571         return error1.isError() == error2.isError()
572                 && error1.isWarning() == error2.isWarning()
573                 && error1.isControl() == error2.isControl()
574                 && Objects.equals(error1.getControlElementCode(), error2.getControlElementCode())
575                 && Objects.deepEquals(error1.getPropertyName().toArray(), error2.getPropertyName().toArray())
576                 && Objects.equals(error1.getPmfmId(), error2.getPmfmId())
577                 && Objects.equals(error1.getIndividualId(), error2.getIndividualId())
578                 && Objects.equals(error1.getMessage(), error2.getMessage());
579     }
580 
581     /**
582      * Create a dummy BaseReferentialDTO bean with the specified id
583      *
584      * @param id the id
585      * @return the BaseReferentialDTO bean
586      */
587     public static BaseReferentialDTO newDummyBaseReferentialBean(int id) {
588         BaseReferentialDTO bean = QuadrigeBeanFactory.newBaseReferentialDTO();
589         bean.setId(id);
590         return bean;
591     }
592 
593     /**
594      * <p>filterLocalReferential.</p>
595      *
596      * @param list a {@link List} object.
597      * @param <E>  a E object.
598      * @return a {@link List} object.
599      */
600     public static <E extends BaseReferentialDTO> List<E> filterLocalReferential(List<E> list) {
601         return filterReferential(list, true);
602     }
603 
604     /**
605      * <p>filterNationalReferential.</p>
606      *
607      * @param list a {@link List} object.
608      * @param <E>  a E object.
609      * @return a {@link List} object.
610      */
611     public static <E extends BaseReferentialDTO> List<E> filterNationalReferential(List<E> list) {
612         return filterReferential(list, false);
613     }
614 
615     /**
616      * <p>filterReferential.</p>
617      *
618      * @param list  a {@link List} object.
619      * @param local a boolean.
620      * @param <E>   a E object.
621      * @return a {@link List} object.
622      */
623     public static <E extends BaseReferentialDTO> List<E> filterReferential(List<E> list, final boolean local) {
624         if (CollectionUtils.isNotEmpty(list)) {
625             return filterCollection(list, input -> isLocalReferential(input) == local);
626         }
627         return new ArrayList<>();
628     }
629 
630     public static boolean isLocalReferential(BaseReferentialDTO dto) {
631         return (dto.getStatus() != null && isLocalStatus(dto.getStatus())) || (dto.getId() != null && dto.getId() < 0);
632     }
633 
634     /**
635      * Return true if the status is a local status (only on local DB)
636      *
637      * @param statusDTO a {@link StatusDTO} object.
638      * @return true for a local status
639      */
640     public static boolean isLocalStatus(StatusDTO statusDTO) {
641         Assert.notNull(statusDTO);
642         return isLocalStatus(statusDTO.getCode());
643     }
644 
645     /**
646      * Return true if the status is a local status (only on local DB)
647      *
648      * @param status a not null Status entity
649      * @return true for a local status
650      */
651     public static boolean isLocalStatus(Status status) {
652         Assert.notNull(status);
653         return isLocalStatus(status.getStatusCd());
654     }
655 
656     /**
657      * Return true if the status code is a local status (only on local DB)
658      *
659      * @param statusCode a {@link java.lang.String} object.
660      * @return a boolean.
661      */
662     public static boolean isLocalStatus(String statusCode) {
663         Assert.notBlank(statusCode);
664         return StatusCode.LOCAL_DISABLE.value().equals(statusCode)
665                 || StatusCode.LOCAL_ENABLE.value().equals(statusCode);
666     }
667 
668 
669     public static boolean isDisabledReferential(BaseReferentialDTO dto) {
670         return dto.getStatus() != null && isDisabledStatus(dto.getStatus());
671     }
672 
673     public static boolean isDisabledStatus(StatusDTO statusDTO) {
674         Assert.notNull(statusDTO);
675         return isDisabledStatus(statusDTO.getCode());
676     }
677 
678     public static boolean isDisabledStatus(String statusCode) {
679         Assert.notBlank(statusCode);
680         return StatusCode.LOCAL_DISABLE.value().equals(statusCode) || StatusCode.DISABLE.value().equals(statusCode);
681     }
682 
683 }