View Javadoc
1   /**
2    * This file is part of Indicators.
3    *
4    * Indicators is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * Indicators is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with Indicators. If not, see <https://www.gnu.org/licenses/>.
16   */
17  package fr.inrae.agroclim.indicators.model.data.phenology;
18  
19  import java.util.Collection;
20  import java.util.HashMap;
21  import java.util.HashSet;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import fr.inrae.agroclim.indicators.model.TimeScale;
27  import fr.inrae.agroclim.indicators.model.data.DataLoadingListenerHandler;
28  import fr.inrae.agroclim.indicators.model.data.ResourcesLoader;
29  import fr.inrae.agroclim.indicators.model.data.Variable;
30  import jakarta.xml.bind.annotation.XmlAccessType;
31  import jakarta.xml.bind.annotation.XmlAccessorType;
32  import jakarta.xml.bind.annotation.XmlElement;
33  import jakarta.xml.bind.annotation.XmlElementWrapper;
34  import jakarta.xml.bind.annotation.XmlTransient;
35  import lombok.EqualsAndHashCode;
36  import lombok.Getter;
37  import lombok.Setter;
38  
39  /**
40   * Proxy to load phenology data.
41   *
42   * Loader is chosen according to properties (XML tag).
43   *
44   * The proxy is initialized from evaluation XML file.
45   *
46   * Last changed : $Date$
47   *
48   * @author $Author$
49   * @version $Revision$
50   */
51  @XmlAccessorType(XmlAccessType.FIELD)
52  @EqualsAndHashCode(
53          callSuper = false,
54          of = {"annualStageBuilder", "fileLoader", "calculator", "deltas",
55          "userHeader"}
56          )
57  public final class PhenologyLoaderProxy extends DataLoadingListenerHandler
58          implements ResourcesLoader<List<AnnualStageData>> {
59      /**
60       * UUID for Serializable.
61       */
62      private static final long serialVersionUID = 2980458089659125675L;
63  
64      /**
65       * Builder of annual stages, using DOY.
66       */
67      @Getter
68      @Setter
69      @XmlTransient
70      private AnnualStageBuilder annualStageBuilder;
71  
72      /**
73       * CSV file.
74       */
75      @XmlElement(name = "file")
76      private PhenologyFileLoader fileLoader;
77  
78      /**
79       * Phenological calculator.
80       */
81      @XmlElement(name = "calculator")
82      private PhenologyCalculator calculator;
83  
84      /**
85       * Number of days to add relative stages.
86       */
87      @XmlElementWrapper(name = "deltas")
88      @XmlElement(name = "delta")
89      @Getter
90      @Setter
91      private List<StageDelta> deltas;
92  
93      /**
94       * Headers of CSV file.
95       */
96      @XmlElement(name = "header")
97      private String[] userHeader;
98  
99      /**
100      * Constructor.
101      */
102     public PhenologyLoaderProxy() {
103         super();
104     }
105 
106     @Override
107     public PhenologyLoaderProxy clone() {
108         final PhenologyLoaderProxy clone = new PhenologyLoaderProxy();
109         clone.fileLoader = fileLoader.clone();
110         clone.userHeader = userHeader;
111         return clone;
112     }
113 
114     /**
115      * @return Phenological calculator.
116      */
117     public PhenologyCalculator getCalculator() {
118         return calculator;
119     }
120 
121     @Override
122     public Map<String, String> getConfigurationErrors() {
123         if (getLoader() == null) {
124             final Map<String, String> errors = new HashMap<>();
125             errors.put("phenology", "error.evaluation.phenology.loader.missing");
126             return errors;
127         }
128         return getLoader().getConfigurationErrors();
129     }
130 
131     /**
132      * @return CSV file
133      */
134     public PhenologyFileLoader getFile() {
135         return fileLoader;
136     }
137 
138     /**
139      * @return loader/calculator for phenology data according to configuration.
140      */
141     private ResourcesLoader<List<AnnualStageData>> getLoader() {
142         if (fileLoader != null) {
143             return fileLoader;
144         } else if (annualStageBuilder != null) {
145             return annualStageBuilder;
146         } else if (calculator != null) {
147             return calculator;
148         } else {
149             return null;
150         }
151     }
152 
153     @Override
154     public Collection<String> getMissingVariables() {
155         throw new RuntimeException("Not implemented for phenology!");
156     }
157 
158     /**
159      * @return headers of CSV file
160      */
161     public String[] getUserHeader() {
162         return userHeader;
163     }
164 
165     @Override
166     public Set<Variable> getVariables() {
167         if (getLoader() == null) {
168             return new HashSet<>();
169         }
170         return getLoader().getVariables();
171     }
172 
173     @Override
174     public List<AnnualStageData> load() {
175         if (deltas != null && !deltas.isEmpty()) {
176             final RelativeAnnualStageCalculator calc = new RelativeAnnualStageCalculator();
177             calc.setDeltas(deltas);
178             final List<AnnualStageData> annualStageDatas = getLoader().load();
179             calc.setAnnualStageDatas(annualStageDatas);
180             return calc.load();
181         }
182         return getLoader().load();
183     }
184 
185     /**
186      * @param value phenological calculator
187      */
188     public void setCalculator(final PhenologyCalculator value) {
189         this.calculator = value;
190     }
191 
192     /**
193      * @param value
194      *            CSV file loader
195      */
196     public void setFile(final PhenologyFileLoader value) {
197         this.fileLoader = value;
198     }
199 
200     @Override
201     public void setTimeScale(final TimeScale timeScale) {
202         // do nothing
203     }
204 }