View Javadoc
1   package fr.ifremer.reefdb.ui.swing.util.table;
2   
3   /*
4    * #%L
5    * Reef DB :: 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.quadrige3.core.dao.technical.Assert;
27  import fr.ifremer.quadrige3.ui.swing.table.PmfmColumnIdentifier;
28  import fr.ifremer.reefdb.dto.ReefDbBeanFactory;
29  import fr.ifremer.reefdb.dto.ReefDbBeans;
30  import fr.ifremer.reefdb.dto.data.measurement.MeasurementAware;
31  import fr.ifremer.reefdb.dto.data.measurement.MeasurementDTO;
32  import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationAware;
33  import fr.ifremer.reefdb.dto.data.sampling.SamplingOperationDTO;
34  import fr.ifremer.reefdb.dto.data.survey.SurveyDTO;
35  import fr.ifremer.reefdb.dto.referential.pmfm.PmfmDTO;
36  import fr.ifremer.reefdb.dto.referential.pmfm.QualitativeValueDTO;
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 ReefDbPmfmColumnIdentifier<R extends AbstractReefDbRowUIModel> extends ReefDbColumnIdentifier<R> implements PmfmColumnIdentifier {
50  
51      private String headerLabel;
52  
53      private String headerLabelTip;
54  
55      private PmfmDTO pmfm;
56  
57      private boolean notMandatoryOverride = false;
58  
59      private final transient PropertyChangeSupport pcs;
60  
61      /**
62       * <p>newId.</p>
63       *
64       * @param propertyName a {@link java.lang.String} object.
65       * @param pmfm a {@link PmfmDTO} object.
66       * @param headerLabel a {@link java.lang.String} object.
67       * @param headerLabelTip a {@link java.lang.String} object.
68       * @param propertyType a {@link java.lang.Class} object.
69       * @param <R> a R object.
70       * @return a {@link ReefDbPmfmColumnIdentifier} object.
71       */
72      public static <R extends AbstractReefDbRowUIModel> ReefDbPmfmColumnIdentifier<R> newId(
73              String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType) {
74          return new ReefDbPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, null, false);
75      }
76  
77      /**
78       * <p>newId.</p>
79       *
80       * @param propertyName a {@link java.lang.String} object.
81       * @param pmfm a {@link PmfmDTO} object.
82       * @param headerLabel a {@link java.lang.String} object.
83       * @param headerLabelTip a {@link java.lang.String} object.
84       * @param propertyType a {@link java.lang.Class} object.
85       * @param decoratorName a {@link java.lang.String} object.
86       * @param <R> a R object.
87       * @return a {@link ReefDbPmfmColumnIdentifier} object.
88       */
89      public static <R extends AbstractReefDbRowUIModel> ReefDbPmfmColumnIdentifier<R> newId(
90              String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType, String decoratorName) {
91          return new ReefDbPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, decoratorName, false);
92      }
93  
94      /** {@inheritDoc} */
95      public static <R extends AbstractReefDbRowUIModel> ReefDbPmfmColumnIdentifier<R> newId(
96              String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType, boolean mandatory) {
97          return new ReefDbPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, null, mandatory);
98      }
99  
100     /**
101      * <p>newId.</p>
102      *
103      * @param propertyName a {@link java.lang.String} object.
104      * @param pmfm a {@link PmfmDTO} object.
105      * @param headerLabel a {@link java.lang.String} object.
106      * @param headerLabelTip a {@link java.lang.String} object.
107      * @param propertyType a {@link java.lang.Class} object.
108      * @param decoratorName a {@link java.lang.String} object.
109      * @param mandatory a boolean.
110      * @param <R> a R object.
111      * @return a {@link ReefDbPmfmColumnIdentifier} object.
112      */
113     public static <R extends AbstractReefDbRowUIModel> ReefDbPmfmColumnIdentifier<R> newId(
114             String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType, String decoratorName, boolean mandatory) {
115         return new ReefDbPmfmColumnIdentifier<>(propertyName, pmfm, headerLabel, headerLabelTip, propertyType, decoratorName, mandatory);
116     }
117 
118     /**
119      * <p>newReadOnlyId.</p>
120      *
121      * @param propertyName a {@link java.lang.String} object.
122      * @param pmfm a {@link PmfmDTO} object.
123      * @param headerLabel a {@link java.lang.String} object.
124      * @param headerLabelTip a {@link java.lang.String} object.
125      * @param propertyType a {@link java.lang.Class} object.
126      * @param <R> a R object.
127      * @return a {@link ReefDbPmfmColumnIdentifier} object.
128      */
129     public static <R extends AbstractReefDbRowUIModel> ReefDbPmfmColumnIdentifier<R> newReadOnlyId(
130             String propertyName, PmfmDTO pmfm, String headerLabel, String headerLabelTip, Class<?> propertyType) {
131         return new ReefDbPmfmColumnIdentifier<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 ReefDbPmfmColumnIdentifier.</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 ReefDbPmfmColumnIdentifier(
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         this.pmfm = pmfm;
164         this.headerLabel = headerLabel;
165         this.headerLabelTip = headerLabelTip;
166 
167         pcs = new PropertyChangeSupport(this);
168     }
169 
170     /** {@inheritDoc} */
171     @Override
172     public Object getValue(R entry) {
173         Object result = null;
174         if (getPropertyName() != null && entry != null) {
175             result = getProperty(entry, getPropertyName());
176         }
177         return result;
178     }
179 
180     private Object getProperty(final Object bean, final String property) {
181         Assert.notNull(bean);
182         Assert.notBlank(property);
183         // might not be assignable
184         Assert.isInstanceOf(MeasurementAware.class, bean);
185 
186         MeasurementAware measurementBean = (MeasurementAware) bean;
187         boolean isIndividual = property.equals(SurveyDTO.PROPERTY_INDIVIDUAL_PMFMS);
188 
189         List<MeasurementDTO> measurements = isIndividual
190                 ? measurementBean.getIndividualMeasurements()
191                 : measurementBean.getMeasurements();
192 
193         MeasurementDTO measurement = ReefDbBeans.findByProperty(measurements, ReefDbBeans.PROPERTY_PMFM_ID, getPmfmId());
194         if (measurement != null) {
195             if (measurement.getPmfm().getParameter().isQualitative()) {
196                 return measurement.getQualitativeValue();
197             } else if (measurement.getNumericalValue() != null) {
198                 return measurement.getNumericalValue();
199             }
200         }
201         return null;
202     }
203 
204     /** {@inheritDoc} */
205     @Override
206     public void setValue(final R entry, final Object value) {
207         if (getPropertyName() != null) {
208 
209             Object oldValue = getValue(entry);
210 
211             setProperty(entry, getPropertyName(), value);
212 
213             // fire property change on entry
214             entry.fireIndexedPropertyChanged(getPropertyName(), getPmfmId(), oldValue, value);
215         }
216     }
217 
218     private void setProperty(final Object bean, final String property, final Object value) {
219         Assert.notNull(bean);
220         Assert.notNull(property);
221         Assert.isInstanceOf(MeasurementAware.class, bean);
222 
223         MeasurementAware measurementBean = (MeasurementAware) bean;
224 
225         boolean isIndividual = property.equals(SurveyDTO.PROPERTY_INDIVIDUAL_PMFMS);
226         List<PmfmDTO> pmfms = isIndividual
227                 ? measurementBean.getIndividualPmfms()
228                 : measurementBean.getPmfms();
229         Assert.isTrue(pmfms.contains(pmfm), "The PMFMU is this identifier is not part of measurements PMFMU");
230 
231         List<MeasurementDTO> measurements = isIndividual
232                 ? measurementBean.getIndividualMeasurements()
233                 : measurementBean.getMeasurements();
234 
235         // assert value and pmfm type
236         if (value != null) {
237             if (pmfm.getParameter().isQualitative()) {
238                 Assert.isInstanceOf(QualitativeValueDTO.class, value);
239             } else {
240                 Assert.isInstanceOf(BigDecimal.class, value);
241             }
242         }
243 
244         SamplingOperationDTO samplingOperation = null;
245         if (bean instanceof SamplingOperationDTO) {
246             samplingOperation = (SamplingOperationDTO) bean;
247         } else if (bean instanceof SamplingOperationAware) {
248             samplingOperation = ((SamplingOperationAware) bean).getSamplingOperation();
249         }
250 
251         MeasurementDTO measurement = ReefDbBeans.findByProperty(measurements, ReefDbBeans.PROPERTY_PMFM_ID, getPmfmId());
252         String measurementProperty;
253         if (pmfm.getParameter().isQualitative()) {
254             measurementProperty = MeasurementDTO.PROPERTY_QUALITATIVE_VALUE;
255         } else {
256             measurementProperty = MeasurementDTO.PROPERTY_NUMERICAL_VALUE;
257         }
258 
259         if (value != null) {
260 
261             // Create measurement if not exists
262             if (measurement == null) {
263                 measurement = ReefDbBeanFactory.newMeasurementDTO();
264                 measurement.setSamplingOperation(samplingOperation);
265                 measurement.setPmfm(pmfm);
266                 measurements.add(measurement);
267             }
268 
269             // Set the correct value
270             if (pmfm.getParameter().isQualitative()) {
271 
272                 // Set the qualitative value
273                 measurement.setQualitativeValue((QualitativeValueDTO) value);
274 
275             } else {
276 
277                 // Set the numerical value
278                 BigDecimal bigDecimal = (BigDecimal) value;
279                 measurement.setNumericalValue(bigDecimal);
280                 // Set digit count (but NOT precision - mantis #37438)
281                 measurement.setDigitNb(bigDecimal.scale());
282 
283             }
284         } else {
285 
286             // remove measurement if value is null
287             if (measurement != null) {
288                 measurements.remove(measurement);
289             }
290         }
291 
292         // create and fire event
293         PmfmChangeEvent event = new PmfmChangeEvent(this, samplingOperation, measurementProperty, value);
294         pcs.firePropertyChange(event);
295     }
296 
297     /**
298      * <p>Getter for the field <code>headerLabel</code>.</p>
299      *
300      * @return a {@link java.lang.String} object.
301      */
302     public String getHeaderLabel() {
303         return headerLabel;
304     }
305 
306     /**
307      * <p>Getter for the field <code>headerLabelTip</code>.</p>
308      *
309      * @return a {@link java.lang.String} object.
310      */
311     public String getHeaderLabelTip() {
312         return headerLabelTip;
313     }
314 
315     /**
316      * <p>Getter for the field <code>pmfmId</code>.</p>
317      *
318      * @return a {@link java.lang.Integer} object.
319      */
320     public int getPmfmId() {
321         return pmfm.getId();
322     }
323 
324     public PmfmDTO getPmfm() {
325         return pmfm;
326     }
327 
328     /**
329      * <p>setNotMandatory.</p>
330      */
331     public void setNotMandatory() {
332         this.notMandatoryOverride = true;
333     }
334 
335     /** {@inheritDoc} */
336     @Override
337     public boolean isMandatory() {
338         return !notMandatoryOverride && super.isMandatory();
339     }
340 
341     /**
342      * <p>setPropertyChangeListener.</p>
343      *
344      * @param listener a {@link java.beans.PropertyChangeListener} object.
345      */
346     public void addPropertyChangeListener(PropertyChangeListener listener) {
347         pcs.addPropertyChangeListener(listener);
348     }
349 
350     public void removePropertyChangeListener(PropertyChangeListener listener) {
351         pcs.removePropertyChangeListener(listener);
352     }
353 
354     private void removeAllListeners() {
355         for (PropertyChangeListener listener : pcs.getPropertyChangeListeners()) {
356             pcs.removePropertyChangeListener(listener);
357         }
358     }
359 
360     public class PmfmChangeEvent extends PropertyChangeEvent {
361 
362         private final SamplingOperationDTO samplingOperation;
363 
364         /**
365          * Constructs a new <code>PropertyChangeEvent</code>.
366          *
367          * @param source            The bean that fired the event.
368          * @param propertyName      The programmatic name of the property
369          *                          that was changed.
370          * @param samplingOperation The measurement.
371          * @param newValue          The new value of the property.
372          */
373         PmfmChangeEvent(Object source, SamplingOperationDTO samplingOperation, String propertyName, Object newValue) {
374             super(source, propertyName, null, newValue);
375             this.samplingOperation = samplingOperation;
376         }
377 
378         public SamplingOperationDTO getSamplingOperation() {
379             return samplingOperation;
380         }
381     }
382 }