View Javadoc
1   package fr.ifremer.dali.ui.swing.util.table;
2   
3   /*
4    * #%L
5    * Dali :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import fr.ifremer.dali.dto.DaliBeanFactory;
27  import fr.ifremer.dali.dto.DaliBeans;
28  import fr.ifremer.dali.dto.data.measurement.MeasurementAware;
29  import fr.ifremer.dali.dto.data.measurement.MeasurementDTO;
30  import fr.ifremer.dali.dto.data.sampling.SamplingOperationAware;
31  import fr.ifremer.dali.dto.data.sampling.SamplingOperationDTO;
32  import fr.ifremer.dali.dto.data.survey.SurveyDTO;
33  import fr.ifremer.dali.dto.referential.pmfm.PmfmDTO;
34  import fr.ifremer.dali.dto.referential.pmfm.QualitativeValueDTO;
35  import fr.ifremer.quadrige3.core.dao.technical.Assert;
36  import fr.ifremer.quadrige3.ui.swing.table.PmfmColumnIdentifier;
37  
38  import java.beans.PropertyChangeEvent;
39  import java.beans.PropertyChangeListener;
40  import java.beans.PropertyChangeSupport;
41  import java.math.BigDecimal;
42  import java.util.List;
43  
44  /**
45   * Colonne identifier pour colonne dynamic.
46   *
47   * @param <R> Objet de la colonne
48   */
49  public class DaliPmfmColumnIdentifier<R extends AbstractDaliRowUIModel>
50          extends DaliColumnIdentifier<R>
51          implements PmfmColumnIdentifier {
52  
53      private final String headerLabel;
54  
55      private final String headerLabelTip;
56  
57      private final PmfmDTO pmfm;
58  
59      private boolean notMandatoryOverride = false;
60  
61      private final transient PropertyChangeSupport pcs;
62  
63      /**
64       * <p>newId.</p>
65       *
66       * @param propertyName a {@link java.lang.String} object.
67       * @param pmfm a {@link PmfmDTO} object.
68       * @param headerLabel a {@link java.lang.String} object.
69       * @param headerLabelTip a {@link java.lang.String} object.
70       * @param propertyType a {@link java.lang.Class} object.
71       * @param <R> a R object.
72       * @return a {@link DaliPmfmColumnIdentifier} object.
73       */
74      public static <R extends AbstractDaliRowUIModel> DaliPmfmColumnIdentifier<R> newId(String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType) {
75          return new DaliPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, null, false);
76      }
77  
78      /**
79       * <p>newId.</p>
80       *
81       * @param propertyName a {@link java.lang.String} object.
82       * @param pmfm a {@link PmfmDTO} object.
83       * @param headerLabel a {@link java.lang.String} object.
84       * @param headerLabelTip a {@link java.lang.String} object.
85       * @param propertyType a {@link java.lang.Class} object.
86       * @param decoratorName a {@link java.lang.String} object.
87       * @param <R> a R object.
88       * @return a {@link DaliPmfmColumnIdentifier} object.
89       */
90      public static <R extends AbstractDaliRowUIModel> DaliPmfmColumnIdentifier<R> newId(String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType,
91                                                                                         String decoratorName) {
92          return new DaliPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, decoratorName, false);
93      }
94  
95      /** {@inheritDoc} */
96      public static <R extends AbstractDaliRowUIModel> DaliPmfmColumnIdentifier<R> newId(String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType,
97                                                                                         boolean mandatory) {
98          return new DaliPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, null, mandatory);
99      }
100 
101     /**
102      * <p>newId.</p>
103      *
104      * @param propertyName a {@link java.lang.String} object.
105      * @param pmfm a {@link PmfmDTO} object.
106      * @param headerLabel a {@link java.lang.String} object.
107      * @param headerLabelTip a {@link java.lang.String} object.
108      * @param propertyType a {@link java.lang.Class} object.
109      * @param decoratorName a {@link java.lang.String} object.
110      * @param mandatory a boolean.
111      * @param <R> a R object.
112      * @return a {@link DaliPmfmColumnIdentifier} object.
113      */
114     public static <R extends AbstractDaliRowUIModel> DaliPmfmColumnIdentifier<R> newId(String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType,
115                                                                                        String decoratorName, boolean mandatory) {
116         return new DaliPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, decoratorName, mandatory);
117     }
118 
119     /**
120      * <p>newReadOnlyId.</p>
121      *
122      * @param propertyName a {@link java.lang.String} object.
123      * @param pmfm a {@link PmfmDTO} object.
124      * @param headerLabel a {@link java.lang.String} object.
125      * @param headerLabelTip a {@link java.lang.String} object.
126      * @param propertyType a {@link java.lang.Class} object.
127      * @param <R> a R object.
128      * @return a {@link DaliPmfmColumnIdentifier} object.
129      */
130     public static <R extends AbstractDaliRowUIModel> DaliPmfmColumnIdentifier<R> newReadOnlyId(String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType) {
131         return new DaliPmfmColumnIdentifier<R>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, null, false) {
132 
133             private static final long serialVersionUID = 1L;
134 
135             @Override
136             public void setValue(R entry, Object value) {
137                 // no set
138             }
139         };
140     }
141 
142     /**
143      * <p>Constructor for DaliPmfmColumnIdentifier.</p>
144      *
145      * @param propertyName a {@link java.lang.String} object.
146      * @param pmfm a {@link PmfmDTO} object.
147      * @param headerLabel a {@link java.lang.String} object.
148      * @param headerLabelTip a {@link java.lang.String} object.
149      * @param propertyType a {@link java.lang.Class} object.
150      * @param decoratorName a {@link java.lang.String} object.
151      * @param mandatory a boolean.
152      */
153     protected DaliPmfmColumnIdentifier(
154             final String propertyName,
155             final PmfmDTO pmfm,
156             final String headerLabel,
157             final String headerLabelTip,
158             final Class<?> propertyType,
159             final String decoratorName,
160             final boolean mandatory) {
161         super(propertyName, null, null, propertyType, decoratorName, mandatory);
162 
163         pcs = new PropertyChangeSupport(this);
164         this.pmfm = pmfm;
165         this.headerLabel = headerLabel;
166         this.headerLabelTip = headerLabelTip;
167     }
168 
169     /** {@inheritDoc} */
170     @Override
171     public Object getValue(R entry) {
172         Object result = null;
173         if (getPropertyName() != null && entry != null) {
174             result = getProperty(entry, getPropertyName());
175         }
176         return result;
177     }
178 
179     private Object getProperty(final Object bean, final String property) {
180         Assert.notNull(bean);
181         Assert.notBlank(property);
182         // might not be assignable
183         Assert.isInstanceOf(MeasurementAware.class, bean);
184 
185         MeasurementAware measurementBean = (MeasurementAware) bean;
186         boolean isIndividual = property.equals(SurveyDTO.PROPERTY_INDIVIDUAL_PMFMS);
187 
188         List<MeasurementDTO> measurements = isIndividual
189                 ? measurementBean.getIndividualMeasurements()
190                 : measurementBean.getMeasurements();
191 
192         MeasurementDTO measurement = DaliBeans.findByProperty(measurements, DaliBeans.PROPERTY_PMFM_ID, getPmfmId());
193         if (measurement != null) {
194             if (measurement.getPmfm().getParameter().isQualitative()) {
195                 return measurement.getQualitativeValue();
196             } else if (measurement.getNumericalValue() != null) {
197                 return measurement.getNumericalValue();
198             }
199         }
200         return null;
201     }
202 
203     /** {@inheritDoc} */
204     @Override
205     public void setValue(final R entry, final Object value) {
206         if (getPropertyName() != null) {
207 
208             Object oldValue = getValue(entry);
209 
210             setProperty(entry, getPropertyName(), value);
211 
212             // fire property change on entry
213             entry.fireIndexedPropertyChanged(getPropertyName(), getPmfmId(), oldValue, value);
214         }
215     }
216 
217     private void setProperty(final Object bean, final String property, final Object value) {
218         Assert.notNull(bean);
219         Assert.notNull(property);
220         Assert.isInstanceOf(MeasurementAware.class, bean);
221 
222         MeasurementAware measurementBean = (MeasurementAware) bean;
223 
224         boolean isIndividual = property.equals(SurveyDTO.PROPERTY_INDIVIDUAL_PMFMS);
225         List<PmfmDTO> pmfms = isIndividual
226                 ? measurementBean.getIndividualPmfms()
227                 : measurementBean.getPmfms();
228         Assert.isTrue(pmfms.contains(pmfm), "The PMFM is this identifier is not part of measurements PMFMs");
229 
230         List<MeasurementDTO> measurements = isIndividual
231                 ? measurementBean.getIndividualMeasurements()
232                 : measurementBean.getMeasurements();
233 
234         // assert value and pmfm type
235         if (value != null) {
236             if (pmfm.getParameter().isQualitative()) {
237                 Assert.isInstanceOf(QualitativeValueDTO.class, value);
238             } else {
239                 Assert.isInstanceOf(BigDecimal.class, value);
240             }
241         }
242 
243         SamplingOperationDTO samplingOperation = null;
244         if (bean instanceof SamplingOperationDTO) {
245             samplingOperation = (SamplingOperationDTO) bean;
246         } else if (bean instanceof SamplingOperationAware) {
247             samplingOperation = ((SamplingOperationAware) bean).getSamplingOperation();
248         }
249 
250         MeasurementDTO measurement = DaliBeans.findByProperty(measurements, DaliBeans.PROPERTY_PMFM_ID, getPmfmId());
251         String measurementProperty;
252         if (pmfm.getParameter().isQualitative()) {
253             measurementProperty = MeasurementDTO.PROPERTY_QUALITATIVE_VALUE;
254         } else {
255             measurementProperty = MeasurementDTO.PROPERTY_NUMERICAL_VALUE;
256         }
257 
258         if (value != null) {
259 
260             // Create measurement if not exists
261             if (measurement == null) {
262                 measurement = DaliBeanFactory.newMeasurementDTO();
263                 measurement.setSamplingOperation(samplingOperation);
264                 measurement.setPmfm(pmfm);
265                 measurements.add(measurement);
266             }
267 
268             // Set the correct value
269             if (pmfm.getParameter().isQualitative()) {
270 
271                 // Set the qualitative value
272                 measurement.setQualitativeValue((QualitativeValueDTO) value);
273 
274             } else {
275 
276                 // Set the numerical value
277                 BigDecimal bigDecimal = (BigDecimal) value;
278                 measurement.setNumericalValue(bigDecimal);
279                 // Set digit count (but NOT precision - report du mantis #37438)
280                 measurement.setDigitNb(bigDecimal.scale());
281 
282             }
283         } else {
284 
285             // remove measurement if value is null
286             if (measurement != null) {
287                 measurements.remove(measurement);
288             }
289         }
290 
291         // create and fire event
292         PmfmChangeEvent event = new PmfmChangeEvent(this, samplingOperation, measurementProperty, value);
293         pcs.firePropertyChange(event);
294     }
295 
296     /**
297      * <p>Getter for the field <code>headerLabel</code>.</p>
298      *
299      * @return a {@link java.lang.String} object.
300      */
301     public String getHeaderLabel() {
302         return headerLabel;
303     }
304 
305     /**
306      * <p>Getter for the field <code>headerLabelTip</code>.</p>
307      *
308      * @return a {@link java.lang.String} object.
309      */
310     public String getHeaderLabelTip() {
311         return headerLabelTip;
312     }
313 
314     /**
315      * <p>Getter for the field <code>pmfmId</code>.</p>
316      *
317      * @return a int.
318      */
319     public int getPmfmId() {
320         return pmfm.getId();
321     }
322 
323     public PmfmDTO getPmfm() {
324         return pmfm;
325     }
326 
327     /**
328      * <p>setNotMandatory.</p>
329      */
330     public void setNotMandatory() {
331         this.notMandatoryOverride = true;
332     }
333 
334     /** {@inheritDoc} */
335     @Override
336     public boolean isMandatory() {
337         return !notMandatoryOverride && super.isMandatory();
338     }
339 
340     /**
341      * <p>setPropertyChangeListener.</p>
342      *
343      * @param listener a {@link java.beans.PropertyChangeListener} object.
344      */
345     public void addPropertyChangeListener(PropertyChangeListener listener) {
346         pcs.addPropertyChangeListener(listener);
347     }
348 
349     public void removePropertyChangeListener(PropertyChangeListener listener) {
350         pcs.removePropertyChangeListener(listener);
351     }
352 
353     private void removeAllListeners() {
354         for (PropertyChangeListener listener : pcs.getPropertyChangeListeners()) {
355             pcs.removePropertyChangeListener(listener);
356         }
357     }
358 
359     public class PmfmChangeEvent extends PropertyChangeEvent {
360 
361         private final SamplingOperationDTO samplingOperation;
362 
363         /**
364          * Constructs a new <code>PropertyChangeEvent</code>.
365          *
366          * @param source            The bean that fired the event.
367          * @param propertyName      The programmatic name of the property
368          *                          that was changed.
369          * @param samplingOperation The measurement.
370          * @param newValue          The new value of the property.
371          */
372         PmfmChangeEvent(Object source, SamplingOperationDTO samplingOperation, String propertyName, Object newValue) {
373             super(source, propertyName, null, newValue);
374             this.samplingOperation = samplingOperation;
375         }
376 
377         public SamplingOperationDTO getSamplingOperation() {
378             return samplingOperation;
379         }
380     }
381 }